见下面的程序段
1 package test; 2 class A { 3 public String f(A obj) 4 { 5 return("A"); 6 } 7 } 8 class B extends A { 9 public String f(B obj) 10 { 11 return("C"); 12 } 13 public String f(A obj) 14 { 15 return("D"); 16 } 17 }
我们使用子类创建一个对象:
B b = new B();
然后再将这个子类的引用放到父类对象中:
A a;
a = b;
那么这个父类对象a是子类对象b的上转型对象,对象的实体由子类负责建立,实质还是子类,只是损失了一些功能而已,这样的得失具体如下:
得:上转型对象可以操作和使用子类继承或者重写的方法。
失:上转型对象丧失了对子类新增成员变量或新增的方法的操作和使用。
那么下边的这段测试代码的打印结果就是“D”,因为a2只能有public String f(A obj) 这个方法是可以用的。
1 public class TestObj 2 { 3 public static void main(String args[]) 4 { A a1 = new A(); 5 A a2 = new B(); //子类对象转化为父类,称为上转型,不需要强制转换。 6 B b = new B(); 7 System.out.println(a2.f(b)); //“D” 8 System.out.println(); 9 10 if (a2 instanceof B) { 11 B b1 = (B) a2; //父类对象转化为下转型,此时需要使用强制转换,此时需要先判断要转换的这个对象(也就是a2指向的这个对象)是不是B类的实例 12 System.out.println(b1.f(b));//"C" 13 System.out.println(b1.f(a1));//"D" 14 } 15 } 16 }
性质
对象的上转型的实体是有子类创建的,但是上转型对象会失去子类的一些属性和功能。上转型对象具有以下特点:
- 上转型对象不能操作子类新增加的成员变量,不能使用子类新增的方法。即为较子类失去一些属性和功能,这些属性和功能是新增的。
- 上转型对象可以操作子类继承或隐藏的成员变量,也可以使用子类继承的或重写的方法。即为上转型对象可以操纵父类原有的属性和功能,无论这些方法是否被重写。
- 上转型对象调用方法时,就是调用子类继承和重写过的方法。而不会是新增的方法,也不是父类原有的方法。
- 可以将对象的上转型对象再强制转换到一个子类对象,强制转换过的对象具有子类所有属性和功能。