花自飘零水自流。一种相思,两处闲愁。

——李清照《一剪梅》

## 1. 面向对象特性之继承

extends

1.1 继承定义

  1. 就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性,相同的行为,子类可以直接询问父类中的非私有的属性和行为

  2. 格式:class 子类 extends 父类{ … };

  3. 好处

    1. 提高代码的复用性

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

  4. 继承和成员变量的特点

    1. 不重名;无影响
    2. 重名:子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用 super关键字,修饰父类成员变量。
  5. Fu 类中的成员变量是非私有的,子类中可以直接访问。若Fu 类中的成员变量私有了,子类是不能直接访问的。通常编码时,我们遵循封装的原则,使用private修饰成员变量,那么如何访问父类的私有成员变量呢?对!可以在父类中提供公共的getXxx方法和setXxx方法。

  6. 继承和成员方法的特点

    1. 不重名:如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。
    2. 重名:如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。

1.2 方法重写

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

  2. 重载和重写:

    1. 重载:方法名相同,参数列表不同。
    2. 重写:方法名相同,参数列表相同。两个方法分布在子类和父类中。 又叫方法的覆盖、覆写。
  3. 重写的最主要的目的:==对原有方法进行功能上的增强。==

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class Phone{
    public void call(){
    System.out.println("打电话");
    }
    public void show(){
    System.out.println("显示号码");
    }
    }
    class Px extends Phone{

    @Override
    public void show() {
    super.show();
    System.out.println("显示来电号码的归属地");
    }
    }
  1. ==方法的重写的特别注意:==
    1. @override 检测当前注解下的(重写)方法是不是对父类方法进行了重写。
    2. 访问权限:public > protected >(default) > private
    3. 返回值类型 Object > String
    4. 父类中被重写的方法的访问权限 <= 子类的重写方法的访问权限。(==正常开发的时候父子类的访问修饰符都是相同的。==)
    5. 父类中被重写的方法的返回值类型要 >= 子类中被重写的方法的返回值类型。

/\/@override** 检测当前注解下的(重写)方法是不是对父类方法进行了重写。创建的是子类的对象,那么就优先使用的是子类的方法。所以重写才有意义。

1.4 继承格式

  1. 如果一个类没有使用extends 继承其他的类,那么默认继承的是Object. Object类是所有类的祖先。所有的类都继承了Object类
  2. 子类继承了父类,那么子类就应该拥有了父亲的所有的属性和方法(局部变量,本类成员变量,父类的成员变量,继承的是父类成员属性和成员方法。)。

1.5 继承关系中-父子类构造方法的访问特点

  1. 子类的构造方法中有一个默认super()会调用,所以一定是先调用了父类的构造方法,然后才执行的子类的构造方法

  2. 子类的构造方法中可以通过 super( )来调用父类的构造方法。

  3. super的在子类的构造器中的位置,必须是在第一语句上。而且子类的构造方法中只能有一个super调用。

  4. 总结:子类是必须调用父类构造方法。不写的话,默认添加一个super();写了的话,则调用指定的父类构造器。super只能有一个,而且必须是第一个语句。//正常来说 super只有在调用有参数的父类构造器的时候才会出现。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class Fu {
    int num = 10;
    public Fu(){
    System.out.println("调用了父类的构造器,无can父类构造器");
    }
    public Fu(int num) {
    System.out.println("调用了父类的构造器,有can父类构造器");
    }
    }
    class Zi extends Fu{
    int age = 10;

    String name ="taoge";

    public Zi(){
    // super();
    super(10);
    //正常来说 super只有在调用有参数的父类构造器的时候才会出现。
    // super();//子类构造器第一行默认有一个super调用了父类的构造器。 super可以不写,默认有,
    // 但是如果写了,只能放在第一行。
    System.out.println("调用了子类的构造器");
    }
    }

1.6 super和this

  1. super:代表的是父类的存储空间(可以理解为父类的引用)

  2. this:代表的是当前对象的引用

  3. 访问成员方法:

    1. super.成员变量 父类的

    2. this.成员变量 本类的

    3. super.成员方法 父类的

    4. this.成员方法 本类的

    5. this(); //调用的本类的构造函数

    6. super(); //调用的父类的构造函数。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      class Fu {
      int num = 5;
      }
      class Zi extends Fu {
      int num = 10;

      public void method() {
      int num = 30;
      //30 局部变量
      System.out.println("num = " + num);
      //10 本类的成员变量
      System.out.println("this.num = " + this.num);
      //5 父类的成员变量
      System.out.println("super.num = " + super.num);
      }
      public void methods(){
      // 有对象调用 this 如果在不产生变量冲突的情况下,this可以省略
      //System.out.println("num = " + this.num);//10
      //10
      System.out.println("num = " + num);
      }
      }
  1. 子类的每个构造方法中均有默认的super()调用父类的空参构造。

  2. 手动调用父类构造会覆盖默认的super()。

  3. super() 和this();都在构造方法的第一行所以不能同时存在。

  4. ==只要创建子类的对象:父类的构造函数一定会被调用==。

  5. 子类的构造函数也一样会被调用,所以我们说:创建对象一定会调用构造函数

1.7 继承的特点

  • Java自支持单继承,不支持多继承

  • Java支持多层继承(继承体系),顶层父类是Object类所有的类默认继承Object,作为父类。

  • 子类和父类是一种相对的概念

1.8 抽象类

  1. 父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了。
  2. 我们把没有方法主体的方法称为抽象方法。
  3. Java语法规定,包含抽象方法的类就是抽象类。
1.8.1 抽象方法
  1. 没有方法体的方法叫抽象方法。
  2. public abstract void eat();所以当前方法的方法体是没有任何作用的。
  3. 抽象方法只有方法名,没有方法体。
  4. 非抽象方法,不需要重写,但是可以重写
1.8.2 抽象类abstract
  1. 包含抽象方法的类叫抽象类。
  2. Abstract class Animal抽象类是无法创建对象的。
  3. 因为每个子类都要去重写当前的方法
  4. 抽象类无法实例化对象:编译不通过。
  5. 一个类继承了抽象类的话,那么这个类应该实现抽象类(重写方法)
  6. 父类要有无参构造方法,如果不加构造方法,会报错。