8.继承和多态
继承
使用场景/使用原因:
父类成员的访问
构造方法
super和this的区别
代码块的执行顺序
访问修饰符
多态
方法重写的规则
继承
使用场景/使用原因:
- 进行共性抽取,实现代码复用
- 继承的双方为父类/基类,子类
关键字:
extends; 格式:class 类名 extends 父类{}- 每个子类都是只有一个直接父类,不支持多继承(但可以使用接口)
- 在主函数中创建子类的实例引用后,可以调用父类的非private成员变量和方法
父类成员的访问
- 访问成员变量
- (条件: Stu是子类,teacher是父类)
Stu student = new Stu( );
student.tName;
- (条件: Stu是子类,teacher是父类)
- 注意:如果父类和子类中有同名的变量时,父子类同名成员变量属于变量隐藏,子类调用时,优先使用自身的成员;若没有就调用父类的,否则就会编译报错
- 当子类对象访问 父类和子类同名方法时
- 若父类和子类同名方法的参数列表不同(重载),根据调用方法适 传递的参数选择合适的方法访问,如果没有就报错
- 同名的实例方法,优先执行子类重写后的方法
- 访问成员变量
- 思考:继承后同名成员会调用子类的,如果想调用父类的的同名成员,应该如何操作?
- 使用super关键字
- 用法:super.成员变量
- tip: 只能在非静态方法中使用(因为静态方法不依赖于对象)
构造方法
- 格式:public 类名(){}
- ⭐子类对象构造时,要先触发基类构造方法,再执行子类的构造方法,并将子类自己新增加的成员初始化完整
- 构造方法和当前的类名相同,可以有参数
- (在子类构造方法中第一行默认隐式调用super() )
- 如果类内没有自定义构造方法时,编译器会给出一个 不含参数的构造函数
super和this的区别
this super 调用位置 构造方法的第一行 构造方法的第一行 指代当前对象/调用实例方法的对象 引用父类的成员
- 相同点:只能在类的非静态方法使用,用来访问非静态成员方法和字段
代码块的执行顺序
- (调用两个实例对象时)
- 父类静态代码块--子类静态代码块--父类实例代码块---父类构造方法--子类实例代码块--子类构造方法
- tip:一个静态代码块只执行一次
访问修饰符
- public >protected> default>private
不同包的非子类--不同包的 子类--相同包的不同类--相同包的相同类/当前类
- public >protected> default>private
- final关键字
- 修饰变量,表示常量(不能修改)
- 修饰类,表示此类不能被继承
- 继承和组合
- 继承是 is-a
- 组合是 has -a/a part of
多态
- 概念:同一行为,不同对象有不同实现;使用父类 引用指向子类对象,调用重写实例方法时发生动态绑定。
- 条件:子类继承了父类;子类重写了父类的方法 且内容不同;通过父类的引用调用重写的方法
父类类型的引用变量,指向子类对象(发生向上转型);调用被子类重写过的那个方法 → 实际跑的是子类重写后的方法 方法重写的规则
- 重写的 方法名 和 参数列表不能改变
- 返回值类型可以不同,但要有父子关系;方法内容不同
- 访问权限不能比父类中被重写的方法的访问权限更低
- 父类被static、private修饰的方法、构造方法都不能被重写
- 向上转型
- 将子类转为父类
- 使用场景
- 直接赋值;方法传参;方法返回
- 向下转型
- 将父类转为子类。需要进行强制类型转化。不一定能转成功
- instanceof关键字,判断是否安全。例:if(animal instanceof Cat)
