多态
多态的必要条件
- 必须存在继承关系
- 必须存在方法重写
- 父类引用指向子类对象
多态访问成员的特点
- 成员变量:编译时期看左边类型,运行时期看左边类型
- 成员方法:编译时期看左边类型,运行时期看右边类型
- 构造方法:帮助子类初始化父类继承过来的成员
- 静态方法:编译时期看左边类型,运行时期看左边类型
多态的优点
- 简化了代码
- 提高了维护性和扩展性
多态的两种实现方式
- 使用父类作为方法的形参实现多态
- 使用父类作为方法返回值实现多态
- 当这个作为参数的父类是普通类或者抽象类时,构成继承多态
- 当这个父作为参数的父类是一个接口时,构成接口多态
多态作为形参
形式参数
基本类型满足类型转换的规则
引用数据类型
普通类
当一个形参希望我们传入的是一个普通类时,我们实际上传入的是该类的对象/匿名对象
抽象类
当一个形参希望我们传入的是一个抽象类时,我们实际上传入的是该类的子类对象/子类匿名对象
接口
当一个形参希望我们传入的是一个接口时,我们实际上传入的是该类的实现对象/实现类匿名对象
多态作为返回值
返回值类型
基本类型
引用类型
普通类
当一个方法的返回值是一个普通的类时,实际上返回的是该类的一个对象,我们可以使用该类的对象接受
抽象类
当一个方法的返回值是一个抽象类时,实际上返回的是该对象类的子类对象,我们可以使用该抽象类接收
接口
当一个方法的返回值是一个接口时,实际上返回的是该接口的实现类对象,我们可以使用接口接收
多态的缺点以及解决办法
缺点:通过多态的引用无法访问子类特有的方法
解决办法:
向上转型(自动转换)
格式:<父类型> <引用变量名> = new <子类型>();
特点:
子类转为父类 父类的引用指向子类对象。自动进行类型转换
此时通过父类引用变量调用的方法是子类覆盖或继承的方法
此时通过父类引用变量无法调用子类特有的属性和放法
向下转型(强制转换)
格式: <子类型> <引用变量名> = (<子类型>) <父类型的引用变量>;
特点:
父类转为子类,父类引用转为子类对象。理解为强制类型转换
在向下转型的过程中,如果没有转换为真实子类类型,会出现类型转换异常
ClassCastException
异常名称:类型转换异常
产生原因:在向下转型的过程中没有转换为真实的类型
解决办法:对父类的所有子类做逐一类型判断
instanceof关键字
格式:左边对象 instanceof 右边类
作用:判断左边对象是否属于右边类的实例,是返回true,不是返回false
目前我们知道使用向下转型 + instanceof关键字能够解决多态的缺点
但是我们清楚 如果需要对父类的所有子类做逐一判断,可能存在安全隐患或者违反开闭原则
但是还有一个Object类,该类有无数个子类,所以如果父类引用是Object,那么安全隐患永远存在