多态的概念:
多态指的一个事物具有多种形态,最终多态体现为父类变量指向子类对象。多态的前提是,须有子父类关系,类实现接口关系。
普通类定义的格式:
父类 变量名=new 子类();
抽象类多态定义的格式:
抽象类 变量名=new 抽象类子类();
接口多态定义的格式:
接口 变量名=new 接口实现类();
多态变量调用成员变量时的特点:
编译时期,如果访问的变量时父类的成员变量,如果不是,编译失败。
运行时期:如果访问子父类相同变量名的变量,则值为父类的。
编译运行都看左边。
多态调用调用成员方法时的特点
编译时期,如果调用的是父类有的方法,编译成功,父类没有,编译失败。
运行时期,如果调用的是子父类都有的方法,则调用子类的方法,如果是父类独有的,调用父类的
编译看左边,运行看右边。
多态的转型:
向上转型:子类对象赋值给一个父类引用时,便是向上转型,即多态本身就是向上转型。
格式:
父类类型 对象=new 子类类型();
向下转型:已经向上转型的子类对象使用强制类型转换的格式,将父类引用转为子类引用,便是向下转型。也就是说前提条件是有向上转型。
格式:
子类类型 变量名=(子类类型) 父类类型的变量
instanceof关键字:
因为父类有多个子类,不确定要转化哪个子类,所以要用instanceof判断某个对象是否属于某种数据类型。
if(p instanceof Teacher){
Teacher t=(Teacher)p;
}
多态的好处与弊端:
当父类的引用指向子类对象时,就发生了向上转型,即把子类类型对象转成了父类类型对象,所以说隐藏了子类类型,提高了代码的扩展性。
但是向上转型只能使用子父类共有的功能,即重写的方法,无法使用子类特有的功能。
当不要面对子类类型时,通过提高拓展性,或者使用父类的功能就能完成相应的操作,这时就使用向上转型。
当使用子类特有的功能时,就使用向下转型。但是当需要面对具体的子类对象时,向下转型容易发生ClassCastException类型转换异常,所以需要用instanceof判断。
Animal a = new Dog();
if (a instanceof Dog) {
Dog b = (Dog) a;
b.eat();
b.lookhome();
}