需要注意的是向上、向下转型之后各个成员变量值的变化
首先来看父类代码
public class Quadrangle {
public int rangle=30;
public void doit() {
System.out.println("父类.doit()");
}
public void doit1() {
System.out.println("父类.doit1()");
}
}
子类代码
public class Parallelogram extends Quadrangle{
public int edges=4;
public int rangle=50;
public void doit() {
System.out.println("子类.doit()");
}
public static void main(String[] args) {
Parallelogram p=new Parallelogram();
System.out.println("子类调用父类的成员属性 angel="+p.rangle); //因为子类又修改了父类中的一个成员属性rangle的值,所以此时p.rangle是子类修改之后的值
Quadrangle q=new Parallelogram();//向上转型
System.out.println("向上转型之后父类对象调用子类成员属性angle="+q.rangle); //向上转型之后,子类又变成了父类,所以之前在子类中修改的rangle的值,将不起作用,此时q.rangle的值仍然是父类中rangle的值
q.doit();
q.doit1();
//System.out.println("向上转型之后父类对象调用子类成员:"+q.edges); //向上转型之后,父类对象不能调用子类的成员属性
Parallelogram r=(Parallelogram) q; //强制向下转型
System.out.println("向下转型之后angle="+r.rangle); //向下转型之后,rangle的值又称为子类修改之后的值了
r.doit1();
r.doit();
}
}
运行结果为:
子类调用父类的成员属性 angel=50
向上转型之后父类对象调用子类成员属性angle=30
子类.doit()
父类.doit1()
向下转型之后angle=50
父类.doit1()
子类.doit()
从运行结果我们可以看到当我们在向上转型之后,我们在子类中对父类的某一个成员属性进行的修改已经不起作用了,这个成员属性还是存的是它在父类中的值,但是当我们在子类中对父类的成员方法进行重写之后,我们把子类向上转型之后,这个成员方法依然还是调用的是子类中的成员方法,如果我们在子类中没有对父类进行重写,那么成员方法还是父类中的成员方法。
当我们进行向下转型之后,父类中的成员属性已经变成了它在子类中的值了,即如果我们在子类中对父类中某一个成员变量进行修改了话,向下转型之后,父类中的这个成员已经变成了它在子类修改之后的值了(其实此时父类由于向下转型,已经相当于一个子类了)。对于成员方法,我们向下转型之后,子类的可以调用父类的成员方法,如果父类的成员方法没有被子类重写,那么成员方法还是父类的,如果父类中的成员方法被子类重写了,那么向下转型之后,成员方法就是子类中的了。
另外我们需要注意的是当我们向上转型之后,父类的对象不能调用子类独有的属性和方法,就如上面例子中,进行向上转型之后,父类的对象不能调用子类和父类相比独有的成员,即edges,但是此时父类的对象可以调用父类和子类所共有的对象,如上面代码中的成员angle,虽然它可以调用共有的成员angle,但是此时angle的值还是它在父类中的值。