Animal类
public class Animal {
public void move() {
System.out.println("动物行动");
}
}
Dog类
public class Dog extends Animal {
@Override
public void move() {
System.out.println("狗四肢行走");
}
public void yap() {
System.out.println("狗:汪汪汪。。。。");
}
}
测试1:
Animal a = new Dog(); // 向上转型
a.move();
输出:狗四肢行走
测试2:
Dog a = (Dog) new Animal(); // 向下转型
a.move();
输出:
Exception in thread "main" java.lang.ClassCastException: animal.Animal cannot be cast to animal.Dog
at animal.Client.main(Client.java:6)
报类型转换错误,Animal不能转成Dog
测试3:
Animal a = new Dog(); // 向上转型
a.move();
Dog d = (Dog) a; // 向下转型
d.move();
d.yap();
输出:
狗四肢行走
狗四肢行走
狗:汪汪汪。。。。
测试1,2,3解析:
测试2,中报错原因:
Dog a直接引用了Animal对象,但是a的本质是Animal对象,a能调用Dog下的其它方法,
但是a如果调用Dog下的方法,肯定是会导致系统异常,所以java这里直接报类型不能转换的错误。
至于更深层次的原因(这个应该是涉及到更加底层的对象的创建和引用,以及相关栈堆的内存分配的原理了),
这些本人涉及的很浅,皮毛都没有。
测试3,不报错的原因:
Animal a的本质是Dog类型,a被Dog d引用(向下转型)就不会报错。
下面对象的引用图:
图一
如图一所示:Dog d 如果调用yap()肯定会报错,因为d引用的是Animal对象,但是Animal对象中无yap()方法。
准确的应该这么说(个人看法):在创建Animal对象后,把引用赋给Dog d时,d无法引用yap()方法(就是d引用不到Dog下的属性方法),导致运行失败。
图二
如图二所示:Animal a的本质是Dog,a将引用复制了给Dog d,d调用yap()方法自然不会出错
总结:向上转型是安全的,向下转型是不安全的。