在Java中使用Upcasting和Downcasting

来源:互联网 发布:机房装修 知乎 编辑:程序博客网 时间:2024/05/02 09:48
package newPackage2;
class Fruit
{
public String location = "Beijing";
public Fruit()
{
System.out.println("This is the base class' constructor " );
}
public void getLocation()
{
System.out.println("Fruit getLocation:" + location);
}
}
class Apple extends Fruit
{
public String location = "Shandong";
public Apple()
{
System.out.println("This is the derived class' constructor " );
}
public void getLocation() //override
{
System.out.println("Apple getLocation:" + location);
}
}
public class Test2
{
public static void main(final String[] args)
{
final Fruit fruit = new Apple(); // upcasting,safe
fruit.getLocation();
System.out.println("fruit.location = " + fruit.location);
System.out.println("((Apple)(fruit)).location = " + ((Apple)(fruit)).location); //downcasting
System.out.println(fruit instanceof Fruit); //true
System.out.println(fruit instanceof Apple); //true
}
}
/*
输出结果:

This is the base class' constructor
This is the derived class' constructor
Apple getLocation:Shandong
fruit.location = Beijing
((Apple)(fruit)).location = Shandong
true
true

fruit.getLocation();语句会导致类Fruit中的getLocation方法的执行还是Apple中的getLocation方法的执行呢?
从输出结果来看:
Apple location:Shandong
是子类Apple中的getLocation方法的执行。这其中,在生成new Apple()时,
getLocaiton方法做了重写(overwrite or override),即使upcasting到其父类对象,其方法仍然保留。
而对于属性location,upcasting成父类对象时,若用fruit.locaiton这样的方式访问,会访问到父类对象的属性。
所以其输出为:Beijing
而(Apple)(fruit)).location则对fruit又做了一次casting:downcasting,访问到的会是子类对象的属性,
故其输出为:Shandong
Object fruit is an instance of class Fruit:true
Object fruit is an instance of class Apple:true
表明,尽管做了upcasting,其实并没有改变对象作为一个类实例的事实,影响比较大的是在于可能做了方法的重写。
而如果子类Fruit中有一个方法getWeight(), fruit.getWeight就会出错,
原因在于子类独有的方法和属性,当进行upcasting后,不能为upcasting后的对象所用。
而如果又downcasting后,则重新可以使用。
还有一点需要注意的是,upcasting总是安全的,而downcasting却不是,
downcast可能会在编译时通过,而在运行的时候报java.lang.ClassCastException异常。
这其实也好理解:一个苹果肯定是一个水果,一个水果却不一定是一个苹果。
*/
原创粉丝点击