继承
对象代表什么, 就得封装对应的数据, 并提供数据对应的行为
对于两种不同的类, 但是具有很多共同的属性的时候我们就想着用继承, 我们可以将共同的属性放置在一个类中, 然后, 只需要新建两个类, 继承共有的类, 然后单独写自己的属性特点
继承类
Java 中提供了一个关键字 extends, 用这个关键字, 我们可以让一个类和另一个类建立联系
public class Student extends Person{}
其中 Student 称为子类 (派生类), Person 称为父类 (基类或超类)
使用继承的好处
可以把多个子类中重复的代码抽取到父类中了, 提高了代码的复用性
子类可以在父类的基础上, 增加其他的功能, 使得子类的功能更加完善
当类与类之间, 存在相同的内容, 并满足子类是父类的一种, 就可以考虑使用继承, 来优化代码
继承的特点
Java 只支持单继承, 不支持多继承,就和人一样,一个人只能由一个爸爸,但是爸爸还可以有爸爸,爷爷也可以由爸爸,这就是多层继承
一个子类只能继承一个父类, 但支持多层继承
多层继承, 子类 A 继承父类 B, 父类 B 可以继承父类 C
虚拟机会自动为类添加继承对象 Object
Java 中所有类都继承自 Object 类。Object 类是 Java 语言中所有类的根类,它定义了一些共同的方法,例如 equals ()、hashCode ()和 toString ()等。如果一个类没有显式地继承任何类,那么它默认会继承 Object 类
Object 自带的有方法
子类到底能继承父类的哪些内容
假设我们的构造方法能够继承的话,那么我们子类继承下来的构造方法就有可能和子类的类名不一致,因为这个传递下来的构造方法的名字是父类的名字
继承成员变量
非私有的变量能够直接继承,并且直接使用
私有的变量能够继承,但是不能直接使用,我们可以利用接口进行使用
非私有变量
私有变量
继承成员方法
在 Java 中,私有方法是不能被继承的主要原因是封装性和安全性。
首先,私有方法是被设计为只能在类内部使用的方法。它们通常用于辅助其他公共方法或内部实现细节,并且不希望被外部类或子类直接调用。将私有方法继承给子类可能会破坏对这些方法的封装性,使得子类可以直接访问并调用这些方法,进而破坏类的设计意图和安全性。
其次,私有方法对于子类来说是不可见的。继承是一种从父类派生出子类的关系,在子类中可以访问和重写父类的方法。然而,私有方法对于子类来说是不可见的,因为它们只能在定义它们的类内部被访问。所以子类无法继承、访问或重写父类的私有方法。
总结起来,私有方法是为了实现封装和保护类的内部实现细节而设计的,不被子类继承是为了确保类的安全性和封装性。如果需要在子类中重用某个方法,可以将该方法定义为受保护的或公共的,以便子类可以继承和使用。
方法并不是一个一个继承的,而是我们在最高一级的类里面定义一个虚方法表,包括:
非 private
非 static
非 final
只有父类的这三种对象才会继承
继承中需要学的点
继承中成员变量的访问特点
就近原则,谁离我近,我就用谁
Super 只能调用一个 super,这个 super 就是类的父类
使用变量的时候,先到本类的成员变量找,然后在到父类的成员变量去找。
成员方法的访问特点
直接调用的话就满足就近原则,谁距离我近,我就用谁
方法的重写
当父类的方法不能满足子类现在的需求了,我们就需要进行子类的重写
书写格式:
在继承体系中,子类中出现了和父类中一模一样的方法声明,我们就称子类的这个方法是重写的方法
@Override 重写注释
- @Override 是放在重写后的方法上,校验子类重写时语法是否正确
- 加入注解后如果有红色波浪线,表示语法错误
- 建议重写方法都加@Override 注解,代码安全,优雅
方法的重写就是覆盖父类传下来的虚方法表
- 重写方法的名称、形参列表必须与父类中的一致。
- 子类重写父类方法时,访问权限子类必须大于等于父类(暂时了解︰空着不写<protected <public),父类时 public ,子类就不能时 protect,private,但是子类的访问权限可以更高一点
- 子类重写父类方法时,返回值类型子类必须小于等于父类,这个一般是在说当父类返回类型是比较大的对象是比如 Animal,那么子类可以是 cat,dog,但是当父类是 dog,cat 类的时候子类不能是 animal 类
- 建议: 重写的方法尽量和父类保持一致。
- 只有被添加到虚方法表中的方法才能被重写
继承中的构造方法
子类的构造函数写的时候是利用这个 super 进行构造的,我们要注意,这个构造也可以用 alt insert 来进行快捷插入
父类的构造方法不会被子类继承
子类中所有的构造方法默认先访问父类中的无参构造,再执行自己。
为什么
- 子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据。
- 子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化。
怎么调用父类构造方法的 - 子类构造方法的第一行语句默认都是: super (),不写也存在,且必须在第一行。
- 如果想调用父类有参构造,必须手动写 super 进行调用。
继承中构造方法的访问特点是什么?
- 子类不能继承父类的构造方法,但是可以通过 super 调用
- 子类构造方法的第一行,有一个默认的 super ();
- 默认先访问父类中无参的构造方法,再执行自己。
- 如果想要方法文父类有参构造,必须手动书写。
This、super 使用总结
This:理解为一个变量,表示当前方法调用者的地址值:
他是一个局部变量,然后再方法调用的时候会产生值
类似 super()