package 多态;
/**
* 多态中涉及的概念:
* -向上转型(upcasting)
* 子类型 -> 父类型
* 又被称为:自动转换类型
* -向下转型(downcasting)
* 父类型 -> 子类型
* 又被称为:强制转换类型
* 注意:无论是哪个类型,两种类型之间必须要有继承关系,没有继承关系,编译无法通过。
*/
public class Test {
public static void main(String[] args){
/**
* new cat()创建的对象的类型是cat,a这个引用的数据类型是Animal,
* 子类型转换为父类型(向上转型)
*/
Animal a = new cat();
/**
* 1、java分为编译阶段和运行阶段
* 2、先进行编译阶段,再进行运行阶段,若编译阶段无法通过,则无法运行
* 如:Animal a = new cat();
* 编译阶段编译器先检查a这个引用的数据类型为Animal,由于Animal.class字节码当中有move()方法,所有编译通过。
* 这个过程称为"静态绑定",编译阶段绑定。
* 3、运行阶段,JVM堆内存当中真是创建的对象是cat对象,所以程序在运行阶段一定会调用cat对象的move()方法。
* 这个过程称为"动态绑定"
* 4、无论cat类有没有重写move()方法,运行阶段一定调用的是cat对象的move方法,因为底层真实对象就是cat对象。
*/
a.move(); //输出 "猫在飞檐走壁!"
/**
* 注意:当以Animal为父类进行对象创建时,在子类中调用的方法需在父类中也可找到,否则报错。
* 如:a.move(); 运行通过,因为Animal和cat当中都有move()方法
* a.catchmouse(); 报错,因为Animal中没有catchmouse方法,catchmouse()方法为cat类特有。
*
* 若想使用子类cat中catchmouse()方法,可使用向下转型。如下
*/
((cat)a).catchMouse(); //输出 :"猫捉老鼠"
/**
* 1、以下代码编译没有问题,因为编译器检查到bird的数据类型是Animal,Animal和Cat之间存在继承关系,此类型叫向下转型,语法合格。
* 2、代码编译通过,但在运行阶段会出现java.lang.ClasscastException异常,因为JVM堆内存中真实存在的对象是Bird类型,Bird对象
* 无法转换成cat对象,Bird和cat之间不存在继承关系,这种异常总在"向下转型"是发生。
*/
Animal bird = new Bird();
cat c = (cat)bird;
/**
* 1、如何避免类型转换异常?
* 使用instanceof运算符
* 2、instanceof语法格式:
* 引用 instanceof 数据类型名
* 3、instanceof运算符的执行结果类型是布尔类型
* 4、关于运算结果true/false:
* 若:(a instanceof Animal)
* true表示:
* a这个引用指向的对象是一个Animal类型
* false表示:
* a这个引用指向的对象不是Animal类型
*5、java规范,在进行强制类型转换之前,建议采用instance运算符进行判断,避免异常
*/
if(bird instanceof cat){ //通俗点就是:bird是一个cat类型的对象
cat c1 = (cat)bird;
c1.catchMouse(); //调用子类特有方法,因为需要调用子类特有方法,所以才需要进行向下转换
}else if(bird instanceof Bird){ //bird是一个Bird类型的对象
Bird b1 = (Bird)bird;
b1.fly(); //调用子类特有方法;最终输出"大鸟在乱飞"
}
}
}
Animal:
public class Animal {
public void move(){
System.out.println("动物在移动!");
}
}
cat:
public class cat extends Animal {
public void move() {
System.out.println("猫在飞檐走壁!");
}
public void catchMouse(){
System.out.println("猫捉老鼠!");
}
}
Bird:
public class Bird extends Animal {
public void move(){
System.out.println("鸟在飞");
}
public void fly(){
System.out.println("大鸟在乱飞!");
}
}