多态
1、java语法允许父类型引用指向子类型对象
2、底层是什么对象,编译器调用的就是谁的方法
封装让类有了独立体的概念
继承让对象之间有了关系
多态让父类型的引用却可以指向子类型的对象,让程序产生了多种类型的概念
第一种为编译期形态,第二种形态为运行期形态
3、什么时候采用向下转型
一、多态的基础语法
1、多态中涉及的概念
1.1向上转型(Upcasting)
子类型转换为父类型,又被称为自动类型转换。
1.2 向下转型 (Downcasting)
指父类型转换为子类型,又被称为强制类型转换。需要使用强制转换符。
注意:无论是向上转型还是向下转型,两种类型之间必须要有继承关系。没有继承关系的不可以进行转换。
二、java的编译阶段和运行阶段
1、Java程序永远都分为编译阶段和运行阶段
2、先分析编译阶段,再分析运行阶段,编译无法通过,根本是无法运行的。
3、
//向上类型转换,自动类型转换。
//父类型引用指向子类型对象
DongWu a1=new Cat();
a1.move();
编译阶段编译器检查a1这个引用的数据类型为DongWu,由于DongWu。class字节码当中有MOVE()方法,所以编译通过了。这个过程称为静态绑定,编译阶段绑定。只有静态绑定成功后才有后续的运行。
4、在程序运行阶段,JVM堆内存中创建的是Cat对象,那么在程序运行的阶段一定会调用Cat对象的move()方法,此时发生了程序的动态绑定,称为运行阶段的绑定。
5、无论Cat类有没有重写MOVE()方法,运行阶段一定调用的是Cat对象的move()方法,因为底层真实对象就是Cat对象
6、父类型引用子类型对象这种机制导致程序在编译阶段和运行阶段绑定两种不同的形态/状态,这种机制可以称为一种多态的语法机制。
7、
Cat a2=(Cat)a1;
a2.move1();
因为在编译阶段编译器检查到a1的数据类型为DongWu类型,从DongWu.class字节码文件中查找move1()方法,最终没有找到该方法,导致静态绑定失败,没有绑定成功,就是编译失败。就没有办法运行,此时就要进行向下转型。
三、异常和异常的处理
3.1、类型转化异常只有在强制类型转换的时候会发生,也就是向下转型的时候存在隐患(编译通过了,但是运行出错了)
例子:
DongWu a3=new Dog();
Cat a4=(Cat) a3;
a4.move1();
//向下转换异常
3.2、异常处理:
使用instanceof运算符可以避免出现以上的错误。
语法格式:
引用 instanceof 数据类型名
以上运算符的结果为布尔类型,结果可能是TRUE/FALSE
例子: a instanceof Cat
TRUE表示a这个引用指向的对象是一个Cat类型
FALSE表示a这个引用指向的对象不是Cat类型
java在规范中要求,在进行强制类型转换的时候,建议采用instanceof运算符进行判断,避免异常的出现,这是一种编程的好习惯。
例子:
DongWu a3 = new Dog();
if (a3 instanceof Cat) {
Cat a5 = (Cat) a3;
a5.move1();
} else if (a3 instanceof Dog){
Dog a6=(Dog) a3;
a6.move2();
}
四、多态的作用
1、面向对象编程的核心:定义好类,然后将类实例化为对象,给一个环境驱使一下,让各个对象之间协作起来形成一个系统。
2、作用:
降低程序的耦合度,提高程序的拓展力。
能使用多态尽量使用多态。
父类型引用指向子类型对象。
核心:面向抽象编程,尽量不要面向具体编程。