多态:多种形态,即,同种类型的对象,表现出得不太形态
1 | Student s = new Student(); |
应用场景:多种权限的用户注册时。
表现形式:父类类型 对象名称 = 子类对象;
多态的前提:1.有继承关系;
2.有父类引用指向子类对象(Fu f = new Zi();)
3.有方法重写;
多态的好处:使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利。
多态调用成员的特点:
变量调用:编译看左边,运行也看左边
编译看左边: javac编译代码的时候,会看左边的父类中有没有这个变量,如果有,编译成功,如果没有编译失败。
运行看左边:java运行代码时,实际获取的就是左边父类中成员变量的值。
方法调用:编译看左边,运行看右边
编译看左边:javac编译代码时侯,会看左边的父类中有没有这个方法,如果有,编译成功,如果没有编译失败
运行看右边:Java运行代码的时候,实际上运行的是子类中的方法
如何理解?
Animal a = new Dog();
成员变量:在子类对象中,会把父类的成员变量也继承下来。父:name,子:name
成员方法:如果子类对方法进行重写,那么在虚方法表中是会把父类的方法进行覆盖的。
多态的优势和弊端:
优势:
1. 在多态形式下,右边对象可以 实现解耦合,便于扩展和维护。
1 | Person p = new Student(); //Person p = new Teacher(); |
2. 定义方法时,使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利。
弊端:
不能直接调用子类的特有功能
原因:当调用成员方法的时候,编译看左边,运行看右边,那么在编译的时候会先检查左边的父类中有没有这个方法,如果没有直接报错.
解决方案:变回子类类型
转换时如果转成其他类型,就会报错//Cat c = (Cat) a;
1 | Animal a = new Dog(); |
1 | //避免转换类型与真实对象类型不一致会报错的解决方案 |
JDK14新特性—判断和强转的合并.
先判断a是否为Dog类型,如果是,则强转为Dog类型,转换之后的变量名为d
如果不是,则不强转,结果直接为false
1 | if(a instanceof Dog d){//Animal a = new Dog(); |