多态
概述
例如:Student类继承了Person类,那么Student的对象,即是一个Student也是Person。
表示:可以将子类(实现类)对象赋值给该类的引用变量,也可以将子类(实现类)对象赋值给父类的引用变量。
代码的最终体现:父类的引用变量指向子类对象。
代码:Person p = new Student();//就像int x = (byte)4;
注:多态必须在继承的前体下。(普通继承,抽象类,接口)
多态的具体情况
类继承普通类
class Fu{ } class Zi{ public static void main(String[] args) { Fu fu = new Zi(); } }
类继承抽象类
abstract class Fu{ } class Zi extends Fu{ public static void main(String[] args) { Fu fu = new Zi(); } }
实现类实现接口
interface Fu { } class Zi implements Fu{ public static void main(String[] args) { Fu fu = new Zi(); } }
多态下的成员特点
- 编译时期:必须在父类中也有该成员的前提下才能调用,否则编译失败。
- 运行时期:使用的是父类的成员变量。
- 简单记:编译看左边,运行也看左边。
成员方法
- 编译时期:必须在父类也有该成员方法的前提下才能调用,否则编译失败
- 运行时期:使用的是子类重写后的成员方法
- 简单记:编译看左边,运行看右边
如果编程父类了,就不能调用子类独有方法。必须变为子类才能调用子类的方法。
继承的方法,父类会调用子类继承重写的方法。
转型
向上转型
子类对象赋值给父类引用变量,多态本身就是向上转型的过程。
格式:
向下转型
在向上转型后,可以通过强制类型转换,将父类引用变量转换成子类引用变量。
格式:
注:
- 如果没有向上转型,直接使用父类对象转换成子类变量,会发生ClassCastException(类型转换异常)。不存在父子关系也没有向上转型就想向下转型会报错,因为它没有下线。
- 如果已经向上转型了,但是多态时的子类类型与强转后的类型不一致,也会发生ClassCastException(类型转换异常)。即转换成了不是原先自己的无关类,因为它的下线错了。
instanceof
功能:
判断对象是否属于指定类型
格式:对象 instanceof 类型
- 结果的情况:
- 没有意义的比较
非多态情况下或者任何一个子类与其父类的比较都是没有意义的 - 有意义的比较
多态情况下,将父类的引用变量与任意一个子类类型作比较,如果向上转型的过程就是通过该子类创建的,则返回true;反之,则返回false。
- 没有意义的比较
总结
什么时候转型
- 向上:
扩展功能时 - 向下:
当要使用子类特有成员时
多态的好处和缺点
- 好处:
将子类对象赋值给父类变量,使用的是这个多态后的父类变量,所以隐藏了子类类型,提高了代码的扩展性 - 缺点:
只能使用父类中的成员,不能使用子类的特有成员,如果想要使用,必须向下转型才能使用
额外
多态向上转型中,变量重名是父类,方法重名用子类。父有变量和方法子没有,全用父的。子有变量和方法父没有用不能调用。除非向下转型。