向上转型—自动转换,没问题
我们分别定义两个类:一个叫做Aniamal;一个叫做Dog,并且让Dog继承于Animal
public class Animal{
public void play(){
System.out.println("玩游戏");
}
}
public class Dog extends Animal{
public void sitDown(){
System.out.println("坐下");
}
}
Animnal dog1 = new Dog();
向上转型也就是自动转型dog会继承父类对象以及父类的方法,但是与此同时,自身特有的方法会丢失,也就是sitdowm方法将无法调用出来
因为dog1是一个Anamial类型的引用,所以是站在动物的角度去看待汪对象。虽然对象还是狗狗,但是只能看到来自于父类宠物定义的play方法了。所以父类引用指向子类对象,只能调用到来自父类的属性/行为
所以为了解决这个问题,也就是要调用子类特有的方法,就要用到向下转型
向下转型—强制转换,有风险
Anamial daog1 = new Dog();
dog1.play();
Dog dog2 = (Dog)dog1;
dog2.sitDown();
这段代码无论编译还是运行都不会有任何问题。
我们先使用Animal类型的dog1指向了狗对象,然后再换成Dog类型的dog2去指向同一个狗对象。前者由于是父类型所以只能看到定义在父类的方法,后者是子类型,当然就可以看到狗对象身上的特有行为了。这种转型是从父类引用转为子类引用,从继承树的角度说就是向下转型。
但是与此同时这也是不安全的,因为一旦有一个cat类也继承了Anamal对象,那么强转也就无法判断转过来的对象是cat类还是dog类。
结论
- 在引用数据类型中,只有有继承关系的类型才能进行类型转换;
- 类型转换只是转换看待对象的引用的类型,对象本身没有也不可能参与转换;
- 父类引用可以自动指向子类对象,但只能访问和调用到来自于父类的属性和行为;
- 子类的引用不能指向父类或其它子类对象,就算强转也会导致运行失败并抛出ClassCastException;
- . 把父类引用赋给子类引用,语法上必须使用强制类型转换,要想运行也成功还必须保证父类引用指向的对象一定是该子类对象(最好使用instance判断后,再强转)