Java面向对象-继承/重写/多态
继承
Java通过extends关键字实现继承,每个类至多有一个直接父类(抛弃了C++多继承,私有继承和保护继承);
子类无法继承父类private成员/,static变量/方法;
- 针对父类private方法,子类同名方法属于自定义方法,不存在方法重写;
重写/覆盖(@Override)
子类方法重写规则
- 方法签名必须想同;
- 重写方法返回值类型/抛出异常类型 <= 父类;
- 重写方法访问权限 >= 父类;
- 重写方法类型 = 父类(同为static方法/实例方法);
方法重写(override)与方法重载(overload)
- 方法重写:发生在父类和子类同名方法之间;
- 方法重载:发生在同一个类中的同名方法之间;
子类访问父类成员(被子类继承)顺序
子类调用父类构造器(内部)
- 子类不继承父类构造器,通过super访问;
- super调用父类构造器,必须出现在子类构造器执行体的第一行;
- 创建任何对象,构造器执行顺序是从所在继承树最顶层类的构造器执行;
子类调用父类实例方法
- 子类调用父类实例方法原则:无论方法重载/重写,优先子类,其后父类;
- 方法签名(signature):方法的方法名和参数列表;
- 子类调用对象方法时,编译器根据方法签名依次检查该子类的重载方法(如果存在),否则查找其父类的同名方法;
- 子类调用父类实例方法时,根据访问控制权限,
- 内部,通过super访问父类方法;
- 外部,通过子类引用无法访问父类重写方法,可访问父类未重写方法;
子类访问父类static成员
- 根据访问控制,通过父类名直接访问父类static变量/方法,无需考虑覆盖;
子类内部访问父类实例变量(内部)
- 无论是否同名,子类默认访问子类变量,通过super访问父类实例变量;
多态(polymorphism)
静态绑定与动态绑定
绑定:确定方法调用主体的过程;Java绑定机制:Java引用类型分为编译时类型和运行时类型;方法调用时的调用主体只有在执行过程中才被决定,而不是在编译时决定;子类对象调用方法时,编译器调用对象方法的方式分为静态绑定与动态绑定;
- 静态绑定:编译时根据定义确定调用方法主体;
- 定义如果是private/static/final/构造器方法,编译器准确知道应该调用哪个方法;
- 动态绑定:运行时确定调用方法的主体;
- 静态绑定:编译时根据定义确定调用方法主体;
- 定义如果是private/static/final/构造器方法,编译器准确知道应该调用哪个方法;
- 动态绑定:运行时确定调用方法的主体;
子类对象调用重载方法顺序
- 方法签名(signature):方法的方法名和参数列表;
- 子类调用对象方法时,编译器根据方法签名依次检查该子类的重载方法,否则查找其父类的同名方法(优先子类,其后父类);
- 虚拟机为每个类创建一个方法表(method table),便于编译器动态选择调用对象方法;
向上转型与向下转型
- 向上转型(upcasting):父类引用指向子类对象。编译器在编译期间仅识别父类变量是父类类型,必须使用强制类型转换将父类类型转换为子类类型;
- 向下转型(downcasting):子类引用指向父类对象。编译器知道子类类型一定是父类类型,允许隐式的向上转型;
- 适用场合:当调用方法时子类自定义方法时;
- 编译阶段通过,可能出现运行抛出异常,存在安全风险,须用instanceof检查;
多态
- 多态:当子类继承父类/接口时重写父类方法,用父类引用向指向子类对象【向上转型】时,
- 编译阶段,父类对象与调用方法进行静态绑定;
- 运行阶段,子类对象与调用方法进行动态绑定(动态绑定的前提是必须通过静态绑定);
- 两种阶段的绑定不一致,导致“多态”;
- 产生多态的必要条件:存在继承关系,存在方法重写,父类引用指向子类对象;
- 多态好处:编程尽量面向父类或抽象类型,通过多态降低了软件的耦合度,增强软件的扩展能力;
intanceof运算符(对象类型转换)
intanceof用于检查对象类型之间强制转换/对象是否实现指定接口,语法格式是:
if(ReferenceName intanceof ClassName/InterfaceName) {
...
}
运算结果返回true,表示引用类型与指定类/接口之间存在继承关系,允许进行强制类型转换;
final/阻止继承
final变量
final修饰的成员变量初始化后不可改变
- final成员变量初始化必须显式初始化;
- final变量可作为“宏变量”,初始值在编译时确定(类比于C++中的const运算符);
- final引用类型,实质上只保证该引用类型变量引用地址不变,并不保证所指向对象不变;
final方法
- final方法不可被重写,向编译器指明静态绑定;
- final方法可以被重载;
- final与abstract不可同时使用;
final类
- final类不可被继承;
- final类中的所有方法自动为final方法;
所有博文来自个人为知笔记,内容多为读书笔记和理解内容;