全套Java教程_Java基础入门教程,零基础小白自学Java必备教程

一、本单元知识点概述

(Ⅰ)知识点概述

全套Java教程_Java基础入门教程,零基础小白自学Java必备教程

 

二、本单元目标

(Ⅰ)重点知识目标

1.方法重写
2.Super和this关键字
3.抽象类

(Ⅱ)能力目标

1.能够写出类的继承格式
2.能够说出super可以解决的问题
3.写出抽象类和写出抽象方法的格式

三、本单元知识详讲

13.1 继承

13.1.1 继承的由来★★★

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要 继承那一个类即可。如图所示:

 全套Java教程_Java基础入门教程,零基础小白自学Java必备教程

 

其中,多个类可以称为子类,单独那一个类称为父类超类(superclass)或者基类。 继承描述的是事物之间的所属关系,这种关系是: is-a 的关系。例如,图中兔子属于食草动物,食草动物属于动 物。可见,父类更通用,子类更具体。我们通过继承,可以使多种事物之间形成一种关系体系。

13.1.2 继承的定义★★★

  • 继承:就是子类继承父类的属性行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接 访问父类中的非私有的属性和行为。

13.1.3 继承的好处★★★★

  • 提高代码的复用性。

  • 类与类之间产生了关系,是多态的前提。

13.1.4 继承的格式★★★

通过 extends 关键字,可以声明一个子类继承另外一个父类,定义格式如下:

1 class 父类 { 
2     ...      
3 }   
4 class 子类 extends 父类 { 
5     ...      
6 }

继承演示,代码如下:

 1 /*
 2  * 定义员工类Employee,做为父类
 3  */ 
 4 class Employee { 
 5     String name; // 定义name属性      
 6     // 定义员工的工作方法      
 7     public void work() {      
 8         System.out.println("尽心尽力地工作");          
 9     }      
10 }  
11 
12 /*  
13 * 定义讲师类Teacher 继承 员工类Employee  
14 */ 
15 class Teacher extends Employee { 
16     // 定义一个打印name的方法      
17     public void printName() {      
18         System.out.println("name=" + name);          
19     }      
20 } 
21 
22 /*  
23 * 定义测试类  
24 */ 
25 public class ExtendDemo01 { 
26     public static void main(String[] args) {          
27         // 创建一个讲师类对象 
28         Teacher t = new Teacher();                         
29         // 为该员工类的name属性进行赋值 
30         t.name = "小明";                         
31         // 调用该员工的printName()方法    
32         t.printName(); // name = 小明                          
33         // 调用Teacher类继承来的work()方法           
34         t.work();  // 尽心尽力地工作    
35     }      
36 } 

13.1.5 继承的特点 ★★★★

  1. Java只支持单继承,不支持多继承。

//一个类只能有一个父类,不可以有多个父类。 
class C extends A{}  //ok      
class C extends A,B... //error
  1. Java支持多层继承(继承体系)。

class A{} 
class B extends A{} 
class C extends B{}

继承后的特点——成员变量

当类之间产生了关系后,其中各类中的成员变量,又产生了哪些影响呢?

  • 成员变量不重名

 1 class Fu { 
 2  // Fu中的成员变量。      
 3  int num = 5;      
 4 }
 5 class Zi extends Fu {
 6    int num2 = 6;      
 7  // Zi中的成员方法      
 8  public void show() {      
 9      // 访问父类中的num,          
10      System.out.println("Fu num="+num); // 继承而来,所以直接访问。          
11      // 访问子类中的num2          
12      System.out.println("Zi num2="+num2);          
13  }      
14 } 
15 class ExtendDemo02 { 
16  public static void main(String[] args) {              
17      // 创建子类对象 
18      Zi z = new Zi();                  
19      // 调用子类中的show方法    
20      z.show();            
21  }      
22 }   
23 演示结果: 
24 Fu num = 5 
25 Zi num2 = 6
  • 成员变量重名

如果子类父类中出现重名的成员变量,这时的访问是有影响的。代码如下:

 1 class Fu { 
 2     // Fu中的成员变量。      
 3     int num = 5;      
 4 } 
 5 class Zi extends Fu { 
 6     // Zi中的成员变量      
 7     int num = 6;      
 8     public void show() {      
 9         // 访问父类中的num          
10         System.out.println("Fu num=" + num);          
11         // 访问子类中的num          
12         System.out.println("Zi num=" + num);          
13     }      
14 } 
15 class ExtendsDemo03 { 
16     public static void main(String[] args) {             
17         // 创建子类对象    
18         Zi z = new Zi();                  
19         // 调用子类中的show方法    
20         z.show();           
21     }      
22 } 
23 演示结果: 
24 Fu num = 6 
25 Zi num = 6

子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用 super关键字,修饰 父类成员变量,类似于之前学过的 this 。 使用格式:

super.父类成员变量名

子类方法需要修改,代码如下:

 1 class Zi extends Fu { 
 2     // Zi中的成员变量      
 3     int num = 6;      
 4     public void show() {      
 5         //访问父类中的num          
 6         System.out.println("Fu num=" + super.num);          
 7         //访问子类中的num          
 8         System.out.println("Zi num=" + this.num);          
 9     }      
10 } 
11 演示结果: 
12 Fu num = 5 
13 Zi num = 6

小贴士:Fu 类中的成员变量是非私有的,子类中可以直接访问。若Fu 类中的成员变量私有了,子类是不能 直接访问的。通常编码时,我们遵循封装的原则,使用private修饰成员变量,那么如何访问父类的私有成员 变量呢?对!可以在父类中提供公共的getXxx方法和setXxx方法。

 

继承后的特点——成员方法

当类之间产生了关系,其中各类中的成员方法,又产生了哪些影响呢?

  • 成员方法不重名

    如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对 应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。代码如下:

 1 class Fu{ 
 2     public void show(){      
 3         System.out.println("Fu类中的show方法执行");          
 4     }      
 5 } 
 6 class Zi extends Fu{ 
 7     public void show2(){      
 8         System.out.println("Zi类中的show2方法执行");          
 9     }      
10 } 
11 public  class ExtendsDemo04{ 
12     public static void main(String[] args) {      
13         Zi z = new Zi();                
14         //子类中没有show方法,但是可以找到父类方法去执行
15         z.show();           
16         z.show2();          
17     }      
18 }

成员方法重名——重写(Override)

如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。

  • 方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效 果,也称为重写或者复写。声明不变,重新实现

代码如下:

 1 class Fu { 
 2     public void show() {      
 3         System.out.println("Fu show");          
 4     }      
 5 } 
 6 
 7 class Zi extends Fu { 
 8     //子类重写了父类的show方法      
 9     public void show() {      
10         System.out.println("Zi show");          
11     }      
12 } 
13 public class ExtendsDemo05{ 
14     public static void main(String[] args) {      
15         Zi z = new Zi();                
16         // 子类中有show方法,只执行重写后的show方法     
17         z.show();  // Zi show          
18     }      
19 } 

重写的应用

子类可以根据需要,定义特定于自己的行为。既沿袭了父类的功能名称,又根据子类的需要重新实现父类方法,从 而进行扩展增强。比如新的手机增加来电显示头像的功能,代码如下:

 1 class Phone { 
 2     public void sendMessage(){      
 3         System.out.println("发短信");          
 4     }
 5     
 6     public void call(){      
 7         System.out.println("打电话");          
 8     }   
 9     
10     public void showNum(){      
11         System.out.println("来电显示号码");          
12     }      
13 }
14 //智能手机类 
15 class NewPhone extends Phone {      
16     //重写父类的来电显示号码功能,并增加自己的显示姓名和图片功能      
17     public void showNum(){      
18         //调用父类已经存在的功能使用super          
19         uper.showNum();          
20         //增加自己特有显示姓名和图片功能          
21         System.out.println("显示来电姓名");          
22         System.out.println("显示头像");          
23     }      
24 }  
25 
26 public class ExtendsDemo06 { 
27     public static void main(String[] args) {             
28         // 创建子类对象           
29         NewPhone np = new NewPhone();                     
30             // 调用父类继承而来的方法         
31             np.call();               
32         // 调用子类重写的方法           
33         np.showNum();      
34     }      
35 }
小贴士:这里重写时,用到super.父类成员方法,表示调用父类的成员方法。
    • 注意事项

      1. 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。

      2. 子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。

  • 继承后的特点——构造方法

    当类之间产生了关系,其中各类中的构造方法,又产生了哪些影响呢? 首先我们要回忆两个事情,构造方法的定义格式和作用。

    1. 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。

    2. 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构 造方法中默认有一个 super() ,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。代 码如下:

 1 class Fu {   
 2     private int n;   
 3     Fu(){     
 4         System.out.println("Fu()");   
 5     }
 6 }
 7 class Zi extends Fu {   
 8     Zi(){     
 9         // super(),调用父类构造方法     
10         super();     
11         System.out.println("Zi()");   
12     }   
13 } 
14 public class ExtendsDemo07{   
15     public static void main (String args[]){     
16         Zi zi = new Zi();   
17     } 
18 } 
19 输出结果: 
20 Fu() 
21 Zi()

13.2 Super和This

13.2.1 super和this的含义 ★★★

  • super :代表父类的存储空间标识(可以理解为父亲的引用)。

  • this :代表当前对象的引用(谁调用就代表谁)。

13.2.2 super和this的用法★★★★

  • 访问成员

this.成员变量     ‐‐    本类的     
super.成员变量     ‐‐    父类的      
this.成员方法名()   ‐‐    本类的        
super.成员方法名()   ‐‐    父类的

用法演示,代码如下:

 1 class Animal {     
 2     public void eat() {         
 3         System.out.println("animal : eat");     
 4     } 
 5 }   
 6 class Cat extends Animal {     
 7     public void eat() {         
 8         System.out.println("cat : eat");     
 9     }     
10     public void eatTest() {         
11         this.eat();   // this  调用本类的方法         
12         super.eat();  // super 调用父类的方法     
13     } 
14 }   
15 public class ExtendsDemo08 {     
16     public static void main(String[] args) {         
17         Animal a = new Animal();         
18         a.eat();         
19         Cat c = new Cat();         
20         c.eatTest();     
21     } 
22 }   
23 输出结果为: 
24 animal : eat 
25    cat : eat  
26 animal : eat
  • 访问构造方法

this(...)     ‐‐    本类的构造方法     
super(...)    ‐‐    父类的构造方法
子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。 super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。

13.3 抽象类

13.3.1 抽象类的由来★★

父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有 意义,而方法主体则没有存在的意义了。我们把没有方法主体的方法称为抽象方法。Java语法规定,包含抽象方法 的类就是抽象类

13.3.2 抽象类的定义★★★

  • 抽象方法 : 没有方法体的方法。

  • 抽象类:包含抽象方法的类。

13.3.3 抽象方法★★★

使用 abstract 关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。

定义格式:

修饰符 abstract 返回值类型 方法名 (参数列表);

代码举例:

public abstract void run();

13.3.4 抽象类★★★

如果一个类包含抽象方法,那么该类必须是抽象类。

定义格式:

abstract class 类名字 {     

}

代码举例:

public abstract class Animal {     
    public abstract void run();   
}

13.3.5 抽象的使用★★★

继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该父 类的抽象方法,否则,从最初的父类到最终的子类都不能创建对象,失去意义。

代码举例:

 1 public class Cat extends Animal {     
 2     public void run (){        
 3         System.out.println("小猫在墙头走~~~");               
 4     } 
 5 } 
 6 
 7 public class CatTest {    
 8     public static void main(String[] args) {             
 9         // 创建子类对象         
10         Cat c = new Cat();                  
11         // 调用run方法         
12         c.run();    
13     }    
14 } 
15 输出结果: 
16 小猫在墙头走~~~

13.3.6 注意事项有哪些★★

关于抽象类的使用,以下为语法上要注意的细节,虽然条目较多,但若理解了抽象的本质,无需死记硬背。

  1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象

    • 理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。

  2. 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。

    • 理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。

  3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

    • 理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设 计。

  4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象 类。

    • 理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有 意义。

四、本单元知识总结

1.继承的好处、格式及特点。
2.super和this关键字的含义和用法。
3.抽象类中抽象的使用。

上一篇:20210502总结


下一篇:机器学习sklearn(86):算法实例(43)分类(22)朴素贝叶斯(五)贝叶斯分类器做文本分类