Java-面向对象-特性-继承

164 阅读4分钟

继承

为什么要有继承?

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

继承性的好处

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

继承性的格式

class A extends B{} 
//A:子类、派生类、subclass 
//B:父类、超类、基类、superclass 

体现:一旦子类 A 继承父类以后,子类 A 中就获取了父类 B 中声明的结构:属性、方法。特别的,父类中声明为 private 的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构。只有因为封装性的影响,使得子类不能直接调用父类的结构而已。

继承性的规定

  • 一个类可以被多个子类继承
  • 一个类只能有一个父类
  • 子父类是相对的概念
  • 如果我们没有显示的声明一个类的父类的话,则此类继承于java.lang.Object类。
class SubDemo extends Demo{} ✅
class SubDemo extends Demo,Demo2{}  ❌

protected关键字

父类中protected关键字修饰的属性与方法,可以在不同包的子类中被访问。具体参见修饰权限的那节。

super

super调用属性与方法

子类中重写了父类的方法,但是在子类中也要用到父类的方法,可以用super关键字来使用父类中的方法。

  • 我们可以在子类的方法或构造器中,通过"super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯去省略这个"super."前提是子类中的没有与父类同名的属性。
  • 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用"super.属性"的方式,表明调用的是父类中声明的属性。实际中也不会/不应该出现与父类同名的属性。
  • 特殊情况:当子类重写了父类中的方法后,我们想在子类的方法中调用父类中被重写的方法时,必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法。

super调用构造器

可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器。但是注意:

  • super(形参列表)的使用,必须声明在子类构造器的首行。
  • 类的构造器中,针对于this(形参列表)super(形参列表)只能二选一,不能同时出现。
  • 在构造器的首行,既没有显式的声明"this(形参列表)"或"super(形参列表)",则默认的调用的是父类中的空参构造器。super()
  • 在类的多个构造器中,至少有一个类的构造器使用了super(形参列表),调用父类中的构造器。
  • 子类在没有显式的定义构造器的情况下,一定也会隐式的调用父类的构造器super()。如果父类没有空参的构造器,只有带参的构造器,子类应该显式的调用父类带参的构造器。

子类对象实例化的过程

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

从过程上看: 当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类构造器,直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类结构,所以才可以看到内存中有父类中的结构,子类对象可以考虑进行调用。

明确:虽然创建子类对象时,调用了父类的构造器,但自始至终就创建过一个对象,即为new的子类对象。