1、面向对象的特征二:继承性

1、为什么要继承?

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

1.1、继承的优势

  • 减少了代码的冗余,提高了代码的复用性
  • 便于功能的扩展
  • 为了之后多态的使用提供了前提

    2、继承的格式?

    class A extends B{}

  • A:子类、派生类、subclass

  • B:父类、超类、基类、superclass

一旦子类 A 继承父类以后,子类 A 中就获取了父类 B 中声明的结构:属性、方法
特别的,父类中声明为 private 的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构。
只有因为封装性的影响,使得子类不能直接调用父类的结构而已。
子类继承父类以后,还可以声明自己特有的属性或方法,实现功能的拓展。
子类和父类的关系:不同于子集与集合的关系。
extends:延展、扩展

3、Java 中关于继承性的规定

Java 中关于继承性的规定:

  • 一个类可以被多个类继承
  • Java 中类的单继承性:一个类只能有一个父类
  • 子父类是相对的概念。
  • 子类直接继承的父类,称为:直接父类。间接继承的父类,称为,间接父类。
  • 子类继承父类后,就获取了直接父类以及所有间接父类中声明的属性和方法。

如果我们没有显式的声明一个类的父类的话,则此类继承于 java.lang.Object 类,所有的 java 类(除 java.long.Object 类之外)都直接或间接地继承于 java.lang.Object 类,意味着,所有的 java 类具有 java.lang.Object 类声明的功能。

2、方法的重写

重写:子类继承父类以后,可以对父类中的方法进行覆盖操作。
应用:重写以后,当创建子类对象以后,通过子类对象去调用父类中同名同参数方法时,执行的是子类重写父类的方法。 即在程序执行时,子类的方法将覆盖父类的方法。

面试题:区分方法的重载与重写(有的书也叫做“覆盖”)

  • 方法的重写Overriding和重载Overloading是Java多态性的不同表现。
  • 重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。
  • 如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。
  • 子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被”屏蔽”了。
  • 如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。

重写的规定

方法的声明:

权限修饰符 返回值类型 方法名(形参列表){
//方法体
}

约定俗称:子类中的叫重写的方法,父类中的叫被重写的方法。

① 子类重写的方法的方法名和形参列表必须和父类被重写的方法的方法名、形参列表相同;
② 子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限,
特殊情况: 子类不能重写父类中声明为private权限的方法;
③ 返回值类型:

  • 父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void;
  • 父类被重写的方法的返回值类型是A引用类型类型,则子类重写的方法的返回值类型可以是A类或A类的子类;
  • 父类被重写的方法的返回值类型如果是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须是:double)。

④ 子类方法抛出的异常不能大于父类被重写的方法抛出的异常;

注意:子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为static的(不是重写)。
因为static方法是属于类的,子类无法覆盖父类的方法。

3、关键字:super

1、super关键字的使用

  • 我们可以在子类的方法或构造器中,通过”super.属性”或”super.方法”的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯去省略这个”super.”
  • 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的
  • 特殊情况:当子类重写了父类中的方法后,我们想在子类的方法中调用父类中被重写的方法时,必须显式的使用”super.方法”的方式,表明调用的是父类中被重写的方法

2、super调用构造器

  • 我们可以在子类的构造器中显式的使用”super(形参列表)”的方式,调用父类中声明的指定的构造器
  • “super(形参列表)”的使用,必须声明在子类构造器的首行!
  • 我们在类的构造器中,针对于”this(形参列表)”或”super(形参列表)”只能二选一,不能同时出现。
  • 在构造器的首行,既没有显式的声明”this(形参列表)”或”super(形参列表)”,则默认的调用的是父类中的空参构造器。super()
  • 在类的多个构造器中,至少有一个类的构造器使用了”super(形参列表)”,调用父类中的构造器。

3、子对象的实例化过程

1、从结果上看

子类继承父类以后,就获取了父类中声明的属性或方法
创建子类的对象中,在堆空间中,就会加载所有父类中声明的属性。

2、从过程上看

当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类构造器, 直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类结构,所以才可以看到内存中有父类中的结构,子类对象可以考虑进行调用
明确:虽然创建子类对象时,调用了父类的构造器,但自始至终就创建过一个对象,即为new的子类对象。