今天看到一个关于子类构造方法的问题代码如下:
public class Test extends BB {
public static void main(String[] args) {
Test a = new Test(5);
}    
private int radius = 1;   
public void draw() {
System.out.println("A.draw(),radius =" + radius);
}    
public Test(int radius) {
this.radius = radius;
System.out.println("A constructor");
}
}
class BB {
private int radius = 10;
public void draw() {
System.out.println("B.draw(),radius =" + radius);
}    
public BB() {
System.out.println("B constructor");
draw();
}
}执行结果:
B constructor
A.draw(),radius =0
A constructor我知道生成子类对象是先调用父类无参构造方法,但是为什么父类构造方法却调用了子类的darw()方法!
有没有人可以解释下,谢谢!

解决方案 »

  1.   

    因为父类的draw()方法被子类重写了这样当子类实例化时,这个实例,无论它是以子类或父类的身份,都只能调用到被重写后的draw()方法。
      

  2.   

    执行结果: 
    B   constructor //调用父类的构造方法
    A.draw(),radius   =0 //调用被子类重写的draw方法,子类的属性还没有被赋值,所以radius是0
    A   constructor //调用子类的构造方法
      

  3.   

    因为方法是通过虚拟表VT(virtual-table)管理的,你可以把它理解为一个map,有一个key,有一个value,它的key就代表方法的签名(暂时简单理解为方法名),它的value就是方法的对应的入口地址,每个类都有自己的VT,你可以简单的理解为,当子类被加载时,先把父类的方法信息put到VT这个map里,然后在put子类的方法信息,这样,子类的方法信息就把父类的方法信息给覆盖掉了,所以你调用的时候,只能找到子类的方法信息。(当然,实际情况不是那么简单,因为子类方法本身还能继续通过super调用父类的同名方法,所以不是那么单纯一个map的key覆盖,这里为了方便理解,你可以暂时对这样的过程有个概念就可以了)