父类
public class Super{
public int value = 111;
public void test(){
System.out.println("super method");
}
}
子类
public class Sub extends Super{
public int value = 222;
public void test() {
System.out.println("sub mothod");
}
}
main方法
Super sup = new Sub();//向上转型
System.out.println(sup.value);
sup.test();
Sub sub = (Sub)sup;//向下转型
System.out.println(sub.value);
sub.test();
结果:
111
sub mothod
222
sub mothod
分析向上转型:
- 结果显示,向上转型后,sup的属性仍是父类的值,方法却变成子类的。
- 这是因为Sub重写了test()方法,这是动态连接。如果Sub中没有test()方法,则调用父类的test()。但注意,如果父类中没有test(),而子类中有,sup是无法调用test()的,编译时候就会出错。
- 关于属性,因为属性是不存在重写的,所以,sup的value还是父类的111。
分析向下转型:
- 结果显示,sub的属性和方法均是Sub自己的属性和方法。
- 但是,如果Sub中没有属性value和方法test(),结果是输出Super的value和test(),这是由于继承。
向下转型有什么应用场景呢?我认为以下这个场景是比较常见和实用的。
首先再定义一个类Sub2,和Sub一模一样:public class Sub2 extends Super{ public int value = 333; public void test() { System.out.println("sub2 mothod"); } }
然后,使用场景是这样的,一个Super[]数组,里面可以放他的任意子类,取出这些子类的时候,只需要用instanceof判断一下类型,然后根据类型相应的向下转型,就可以取出各种子类以及信息。
Super[] sups = new Super[]{new Sub(),new Sub2()};//向上转型 for(Super sup : sups){ if(sup instanceof Sub){ Sub sub = (Sub)sup;//向下转型 System.out.println(sub.value); } if(sup instanceof Sub2){ Sub2 sub2 = (Sub2)sup;//向下转型 System.out.println(sub2.value); } }
输出:
222 333