概述
- 引入:若编写三个类,学生类,班主任类,老师类,它们之间会存在大量重复代码,Java据此引入了继承这一机制.
- 可以通过抽取三个类的共有属性和共有行为,将其放入一个新类
- 新类称为父类(superclass)或超类,基类
- 旧有的三个类为子类
- 作用:继承说明的是事物之间的所属关系,可以提高代码的复用率
- 格式:
通过extends关键字,可以声明一个子类继承自另一个父类
修饰符 class 父类{
...
}
修饰符 class extends 父类{
...
}
- 注意:父类和子类要有明显的从属关系
- 父类:人 子类:学生
- 父类:人 子类:动物
继承特点
- Java只支持单继承,不支持多继承,但支持多层继承.
- 即一个子类只能继承一个父类(可以类比为一个儿子不能有两个父亲)
- 子类的父类还可以继承另一个父类(可以类比为一个儿子可以有爷爷)
- 这个所谓的"爷爷类"即为间接父类,"父亲类"即为直接父类
- 应该注意的一点:所有类都直接或间接继承于object类
- object类为Java源码中定义的一个类.
可继承内容
构造方法 | 非私有 不能 | private 不能 |
成员变量 | 非私有 能 | private 能 |
成员方法 | 虚方法表 能 | 其他 不能 |
- 构造方法为什么不能?
- 从语法来看,构造方法是修饰符 类名
- 父类的构造方法是修饰符 父类名
- 子类的构造方法是修饰符 子类名
- 而构造方法是在创建对象时根据类名调用的
- 从语法来看,构造方法是修饰符 类名
- private的成员变量为什么能?
- 创建对应的类的对象时,会在堆开辟对应的空间存储成员变量
- 这个对象的空间储存有它以及它的父类的成员变量
- 只是因为父类有private关键字,只能在父类里调用
- 此情况可以在父类里添加set和get方法进行访问和赋值
- 创建对应的类的对象时,会在堆开辟对应的空间存储成员变量
- 在虚方法表中的成员方法为什么能?
- 虚方法为没有private,static,final关键字的方法
- 在多层继承中,非虚方法若想调用,JVM必须一级一级地查找
- 如果多层继承太多次,调用会消耗大量算力
- Java会从最高级父类开始依次设置虚方法表,来存放经常使用的方法来避免级级查找
- A类继承于B类,B类继承于C类
-
A类 B类 C类 虚方法表 虚方法表 虚方法表 在B的基础上再加自己的虚方法 在C的基础上加自己的虚方法 从最高级开始设置虚方法 - 经常使用的方法为没有private,static,final关键字的方法
- private是私有化的方法,无需多说
- static是静态方法,可以直接调用,存储在静态方法区,不会被继承
- final最终的,有此关键字无法被继承
- 经常使用的方法为没有private,static,final关键字的方法
继承与成员变量
- 就近原则(当没有super.和this.时)
- 当子类和父类的成员变量不同时,正常访问
- 当子类和父类的成员变量相同时,访问临近的成员变量
- super.
this.- 用this.变量调用时,调用子类变量,没找到的话,自动调用父类变量
- 用super.变量调用时,调用父类变量
继承与成员方法
- 就近原则(当没有super.和this.时)(与成员变量的规则一致)
- 当子类和父类的成员方法不同时,正常访问
- 当子类和父类的成员方法相同时,访问临近的成员方法
- super. (与成员变量的规则一致)
this.- 用this.方法调用时,调用子类方法,没找到的话,自动调用父类方法
- 用super.方法调用时,调用父类方法
- 方法重写
- 子类继承的成员方法可能不能满足子类的需求.
- 此时重写该成员方法即可
- 方法重写要求子类方法名和父类方法名相同,形参列表也要相同
- @override放在重写的方法上一行,用于检验方法重写是否满足语法
- 同时也方便程序员进行阅读和查找
- 注意:子类访问权限>=父类
- 子类返回值类型<=父类
- 私有方法不能重写
- 静态方法不能重写
- 补充1
- 子类继承的成员方法可能不能满足子类的需求.
class Dog{
void eat{
System.out.println("觅食");
}
}
class PetDog{
@override
void eat{
System.out.println("吃狗粮");
}
}
继承与构造方法
- 子类中所有的构造方法默认先访问父类中的无参构造方法,再执行自己
- 子类在初始化时,可能用到父类成员变量,
- 所以默认访问父类的无参构造来初始化它
- 子类构造方法若没写super(),JVM会自动加一个
- 且super()必须在第一行
- 子类在初始化时,可能用到父类成员变量,
- 若要调用父类的有参构造方法,必须先编写一个子类的有参构造方法
- 再在其中手动编写一个super(参数)
- 一定要求为super(参数)
- super参数列表为空则只会调用父类的无参构造方法
- 再在其中手动编写一个super(参数)
- this()的作用是调用子类的其他构造方法
- 首先编写一个子类的构造方法,再在其中编写this(参数)
- 它必须放在第一行,否则报错
- 它便会再次调用子类的有参构造方法
- 并且它会挤掉默认的super(),使其不在调用父类的无参构造方法
- 但有this(参数)说明子类还有其他的构造方法,其他的方法含有super()
- 父类依旧会因此初始化
希望这杯Java能够如你心意,还请多多一键三连哦.
重写本质是覆盖子类虚方法表中的父类方法,
但父类的虚方法表中的该方法没有被覆盖 ↩︎