一,多态的概念
面向对象的三大特性:封装、继承、多态
多态的前提是继承关系或者实现关系
生活中的多态:不同人物角色在不同的场景下具有不同的身份
程序中的多态:“一个子类就是一个父类”,父类的引用变量指向子类对象,从而形成多态。
写法:
// 例如:Stdeunt继承了Human class Student extends Human{ } Human h = new Student(); // 父类 变量名 = new 子类();
interface Net{ } class Phone implements Net{ } Net n = new Phone; // 接口 变量名 = new 实现类();
二,多态下成员的特点
2.1 成员变量的特点
编译时期:父类中没有这个变量,编译失败;父类中有这个变量,编译通过。
运行时期:访问的是父类中的成员变量
小结:编译运行都看左边。
注:多态的情况下,不能访问子类的特有属性
2.2 成员方法的特点
编译时期:父类中没有这个方法,编译失败;父类中有这个方法,编译通过。
运行时期:调用的是子类中的成员方法
小结:编译看左边,运行看右边。
注:多态的情况下,不能访问子类的特有方法
三,多态的应用
适用场景1:使用父类作为方法的形参,使方法的实参更加灵活,因为此时方法的实参可以是该父类的任何一个子类。
适用场景2:适用父类作为方法的返回类型,使方法的返回更加灵活,因为此时方法的返回类型可以是该父类的任何一个子类。
适用场景3:当使用匿名内部类的方式来创建抽象类的子类对象或者接口的实现类对象时,可以使用抽象类或者接口的引用变量来接收这个匿名对象,此时这个匿名对象有了引用变量名后就可以通过该变量反复调用匿名内部类中的成员。
四,多态的转型问题
4.1 向上转型
多态的本质就是向上转型,父类的引用变量指向子类对象
注:向上转型是不会发生异常的,一定是安全的
多态也就是向上转型后的弊端是无法访问子类的特有内容
4.2 向下转型
多态的情况下,无法访问子类的特有内容,需要向下转型
格式:
子类 变量名 = (子类/实现类)父类/接口引用变量;
Human h = new Teacher(); Teacher t = (Teacher)h; t.teach();// 特有方法 System.out.println(t.age);// 特有属性
注:在进行向下转型的过程中,如果强转的目标类型不是多态时指定的类型会发生
类型转换异常(ClassCastException)
避免类型转换异常需要使用关键字 instanceof
格式:
对象 instanceof 类型
作用:判断对象是否是根据指定类型创建的;判断对象是否可以通过指定的类型来创建。返回布尔值。
instanceof 的细节:
- 没有多态使用 instanceof 是没有意义的
- 在没有多态的情况下使用 instanceof 连接一个除自己和父类以外的任何类都会编译失败
- 在多态下,instanceof 后连接的是父类名是没有意义的,因为结果永远为真
- 在多态下,instanceof 后连接的当前继承体系之外的任何类时都会编译失败