**
面向对象特征之多态机制
**
*关于多态中涉及到的几个概念:
-
-向上转型(upcasting):又被称为自动类型转换
子类型 --> 父类型
-
-向下转型(downcasting):又被称为强制类型转换【需要加强制类型转换符】
父类型 –-> 子类型
- 注: 无论是向上转型还是向下转型,两种类型之间必须要有继承关系。没有继承关系无法编译通过。
*java中允许:父类型引用指向子类型对象
例:
【Cat类继承Animal类,Animal中有move方法,Cat中有move方法和 catchMouse方法】
Animal a2 = new Cat();
a2.move();
//编译阶段编辑器检查a2这个引用的数据类型为Animal,由于Animal.class字节码当中有move()方法,所以编译通过,这个过程称为静态绑定,编译阶段绑定。
//在程序运行阶段,JVM堆内存当中真实创建的对象是Cat对象,那么程序在运行阶段一定会调用Cat对象的move()方法,此时发生了程序的动态绑定,运行阶段绑定。
//无论Cat类有没有重写move方法,运行阶段一定调用的是Cat对象的move方法(若没有重写调用从父类继承过来的move方法),因为底层真实对象就是Cat对象。
//父类型引用指向子类型对象这种机制,导致程序存在编译阶段绑定和运行阶段绑定两种不同的形态/状态,这种机制称为一种多态语法机制。
a2.catchMouse();//编译出错;
//Animal类中不含有catchMouse方法
//如果想让以上语句编译通过,将a2强制类型转换为Cat类型。
**Cat c2 = (Cat)a2;
c2.catchMouse();**
*什么时候需要使用向下转型呢?
当调用的方法是子类中特有的,在父类当中不存在,在想要调用子类特有的方法时必须进行向下转型。
***Animal a3 = new Bird();
Cat c3 = (Cat)a3;**
- //以上程序编译阶段没有问题,因为编译器检查到a3的数据类型是Animal,Animal和Cat之间存在继承关系,并且Animal是父类型,Cat是子类型,父类型转换成子类型叫做向下转型,语法合格。
- //但是程序运行阶段会出现类型转换(java.lang.ClassCastException),这种异常总是在“向下转型”的时候发生。
***怎么避免向下转型时出现的类型转换异常?**
使用**instanceof运算符**。
**怎么用?
-语法格式:
(引用 instanceof 数据类型名)
例如:(a instanceof Animal)
-以上运算符执行结果类型是布尔类型,true/false
true表示:
a这个引用指向的对象是一个Animal类型
false表示:
a这个引用指向的对象不是一个Animal类型
例:
if(a3 instanceof Cat){
Cat c3 = (Cat)a3;
c3.catchMouse();
}
*面向对象编程的核心:
定义好类,然后将类实例化为对象,给一个环境驱使一下,让各个对象之间协作起来形成一个系统。
*多态的作用
降低程序的耦合度,提高程序的扩展力。
示例:
public class PolymorphicTest01 {
public static void main(String [] args) {
//向上转型
PolymorphicTest01 a1 = new Cat();
PolymorphicTest01 a2 = new Bird();
a1.move();
a2.move();
//向下转型【访问子类中特有的方法时】
if(a1 instanceof Cat) {
Cat c1 = (Cat) a1;
c1.catchMouse();
}
}
public void move() {
System.out.println("动物在走");
}
}
class Cat extends PolymorphicTest01{
public void move() {
System.out.println("猫在走猫步!");
}
public void catchMouse() {
System.out.println("猫吃老鼠");
}
}
class Bird extends PolymorphicTest01{
public void move() {
System.out.println("鸟在飞");
}
}
运行结果:
猫在走猫步!
鸟在飞
猫吃老鼠