继承
[TOC]
面向对象三大特征:封装、继承、多态
- 封装:对象代表什么,就得封装对应的数据,并且提供数据对应的行为
继承
在java当中,提供了一个关键字:extends ,使用这个关键字可以让一个类与另一个类建立起继承关系。
栗子:
1 | public class Student extendes Person{}; |
上面的代码中:Student称为子类(派生类),Person称为父类(基类或者超类)。
使用继承的好处:
- 可以把多个子类中重复的代码抽取到父类当中,提高了代码的复用性
- 子类可以在父类的基础上,增加其他的功能,使得子类更加强大。
自己设计
什么时候会用到继承:当类与类之间,存在相同(共性)的内容,并且满足子类是父类其中的一种是,就可以考虑使用继承。
比如:
| 学生 | 老师 |
|---|---|
| 姓名 | 姓名 |
| 年龄 | 年龄 |
| 性别 | 性别 |
| 学习 | 教书 |
可以看到学生和老师都有姓名、年龄、性别这几个属性。那么就可以把这几个属性提取出来,放到父类里面。
继承中的特点
一句话概括:java只支持单继承,不支持多继承,但是支持多层继承
- 单继承:一个子类只能继承一个父类(一个儿子只能有一个父亲)
- 不支持多继承:子类不能同时继承多个父类(一个儿子不同同时有多个父亲)
- 多层继承:子类A可以继承父类B,父类B可以继承父类C,父类C是子类A的间接父类
java中有一个类是所有类的祖宗:Object。java中的每一个类都直接或者间接继承于Object。
注意:子类只能访问父类中非私有的成员。
继承可以继承父类中哪些内容
父类中会有以下三种东西:
- 构造方法
- 成员变量
- 成员方法
根据其中是否私有,可以继承的情况分下面几类:
| 非私有是否能继承 | 私有是否能继承 | |
|---|---|---|
| 构造方法 | 不能 | 不能 |
| 成员变量 | 能 | 能 |
| 成员方法 | // | // |
其中成员方法:只有能够添加到虚方法表中的方法才能被继承。也就是说除了private、final、static修饰的方法,都可以被继承。
继承中成员变量访问特点
就近原则:谁离我近,我就用谁
例子:
1 | public class Fu(){ |
先在局部位置找,本类成员位置找,父类成员位置找,逐级往上。
继承中成员方法的访问特点
直接调用满足就近原则:谁离我近,我就用谁
super关键字
用来显示访问父类成员或者构造方法。
super调用:直接访问父类。
可以使用supper.父类方法来调用父类的方法;可以使用super.父类属性来调用父类的属性。
调用父类的构造方法:
在子类中使用够惨构造方法,在方法里面使用super(父类的参数)。
例子:
1 | public static void main(String[] args){ |
同样的如果调用方法时,前面加了super,那么就会直接去调用父类的方法。
前面加了this,就会调用本类的方法。
方法的重写
当父类的方法不能满足子类现在的需求时,就需要进行方法的重写。
书写格式:
在继承体系中,子类出现了和父类一模一样的方法声明,我们就称子类的这个方法是重写的方法。
- @Override 重写注解
- @Override 是放在重写后的方法上,用来校验子类重写是语法是否正确。
- 加上注解之后如果有红色的波浪线,表示语法错误。
- 建议重写方法都加@Override注解,代码安全优雅
如果在子类重写了方法,那么这个方法就会覆盖掉父类的方法。
方法重写注意事项与要求
- 重写方法的名称、形参列表必须与父类当中的一致。
- 子类重写父类方法时,访问权限子类必须大于等于父类。(空着不写 < protected < public)
- 子类重写父类方法时,返回值类型子类必须小于等于父类。(了解)
比如: 父类为animal 子类为cat和dog:那么子类返回的范围就不能不animal还大 - 重写的方法尽量与父类保持一致
- 只有添加到虚方法表的方法才能被重写。
方法重写的本质:
覆盖虚方法表中的方法
继承中构造方法的特点
- 父类中的构造方法不会被子类继承
- 子类当中所有的构造方法都会先默认访问父类中的无参构造,再执行自己。
为什么呢?
- 因为子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据
- 子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化
怎么调用父类构造方法?
- 子类构造方法的第一行语句默认都是:super(),不写它也在,并且必须在第一行。
- 如果想调用父类有参构造,必须手动写super进行调用
this,super总结
- this可以理解为一个变量,里面存着当前方法调用者的地址值。
- super表示父类的存储空间
| 关键字 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
|---|---|---|---|
| this | this.成员变量 访问本类成员变量 | this.成员方法(…) 访问本类成员方法 | this(…) 访问本类方法 |
| super | super.成员变量 访问父类成员变量 | super.成员方法(…) 访问父类的成员方法 | super(…) 访问父类的构造方法 |