继承(inheritance)
基本概念:
- 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
- 继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
- 已存在的类称为:超类(superclass)、 基类(base class)或父类(parent class)。
- 新类称为:子类(subclass)、派生类(derived class )或孩子类(child class)。
- 子类继承父类后,继承到了父类所有(非private的)属性和方法,并且子类可以拓展具有父类所没有的一些属性和方法。
格式:
public class 父类 {
//父类的实例变量
//父类的方法
}
public class 子类 extends 父类 {
//扩展的新实例变量(视具体需求添加)
//扩展的新方法(视具体需求添加)
//覆盖的父类方法(视具体需求添加)
}
注意:
- 在调用方法时,Java虚拟机首先会在继承树最下方的子类中找覆盖的方法,若没有则去上层的父类中找 ,直到找到为止。
- Java支持多层继承,但不支持多继承。(多继承会存在安全隐患,因为当继承的多个类都存在相同的属性或方法名相同方法体不同的方法,子类进行调用时,就会产生不知道该调用哪一个类中的方法的情况)
- Java会给每一个没有设置父类的类,自动添加一个父类即Object类(Object类在
java.lang
包中,不需要import
—<导入包的关键字>。) - 继承使类与类之间产生
is-a
关系。(子类is-a
父类) - 如果类Y是extends类X,且是类Z是extends类Y,则Z应该能通过
is-a X
的测试。
重写/覆盖(Override):
- 覆盖方法:在子类中,如果定义了方法名、参数列和返回值都与父类完全相同的方法,那么子类中的这个方法就可以称之为覆盖了父类中的方法。
- 覆盖的规则:
- 参数相同,返回类型兼容:不管父类使用了哪种参数,覆盖此方法的子类也一定要使用相同的参数(参数个数 、参数类型 、参数顺序三者都得相同)。无论父类声明的返回类型是什么,子类必须要声明返回一样的类型或该类型的子类。
- 不能降低方法的存取权限:这代表存取权必须相同,或者更加开放。例如不能覆盖掉一个public的方法并将它标记为private。
注意:
- 要想在子类中调用父类中被覆盖掉的方法就需要用 super 关键字。(例如,super.父类方法名)
- 实例变量无法被覆盖。
- 当某个方法在子类中被覆盖过,调用这个方法时会调用到覆盖过的版本。
- 父类的成员方法只能被它的子类重写。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
- 如果不能继承一个方法,则不能重写这个方法
- 声明为final的方法不能被重写。
- 声明为static的方法不能被重写,但是能够被再次声明。
重载(overload):
- 在同一个类中,定义了多个方法名相同,参数列(参数个数 、参数类型 、参数顺序)不同的方法。
- 什么叫:
参数列不同主要有以下三种区分方式:
- 参数的数量不同,例如method(int)和method(int,int)
- 参数的类型不同,例如method(int)和method(String)
- 参数的顺序不同,例如method(int,String)和method(String,int)
注意:
- 参数的顺序不同的前提必须是顺序不同的几个参数类型不能一样,例如如果是method(int,int)的话,那么不管怎么改变顺序都无法进行区分的。
- 重载关心的只是参数。
- 重载只发生在一个类中。
区别 | 覆盖 | 重载 |
实现上 | 子类对父类方法的重写 | 同一个类中建立多个同名方法 |
参数 | 与父类方法同名同参 | 与别的方法同名不同参 |
返回 | 子类与父类返回类型要一致 | 无此要求 |
权限 | 子类不能覆盖父类的private方法 | 无此要求 |
父类一个方法只能在子类覆盖一次 | 重载只要参数不同,可以多次 | |
覆盖是针对父类方法的重写 | 同类中的方法均可重载 | |
重写要求子类比父类抛出更少的异常 | 无此要求 |