public class A { int x=1;
public A(){
     //this.x=1;
     System.out.println(this.x);
     System.out.println(this.getClass());
     print();
    }
void print(){
System.out.println("A:"+this.x);
}
}public class B extends A {
    int x=2;
    public B(){
    
     System.out.println(this.x);
     System.out.println(this.getClass());
     print();
    }
    void print(){
System.out.println("B"+this.x);
}
}public class Test { public static void main(String[] args) {

A b=new B();
B c=new B(); System.out.println(b.x);
System.out.println(c.x); }}运行结果:1
class test02.B
B:0
2
class test02.B
B:2
1
class test02.B
B:0
2
class test02.B
B:2
1
2
请各位高手帮我看看,实在是看不明白为什么是这样

解决方案 »

  1.   

    下次请你把输出格式规范一下。看的我眼都花了。
    我给你解释一下这是为什么。
    先说 A b=new B();情况。
    首先因为B是继承自A。当创建new B()时。根据初始化顺序。
    首先开始初始化A。

    1、为A开辟一块内存空间,将内存空间清空。(在A中定义的所有变量变为0以及null),对B执行同样操作

    2、初始化A所有的静态方法以及静态变量。
    3、初始化B所有的静态方法以及静态变量。
    4、开始初始化A所有的变量
    4、开始调用A的构造方法(因为B继承自A。在B的内部隐藏维护了一个A的对象)。
    执行System.out.println(this.x);
    因此打印出
    1
    然后执行
    System.out.println(this.getClass());
    由于是调用的方法。根据动态绑定。因此该方法被捆绑到了B对象。调用的就是B的getClass();
    因此打印出
    class test02.B
    然后调用
     print();方法。仍然是动态绑定。因此实际调用的是B中的print()方法。注意我第一条说的。
    这个时候只是给B分配了内存空间,并且清零操作。但是没有真正的初始化变量。因为所有的变量值为0或者Null。
    因此打印出
    B:0----------------------------------------------
    然后开始对B执行初始化操作。
    然后调用构造方法。B这里就不用解释了。
    因此打印出
    2
    class test02.B
    B:2--------------------------------------------
     B c=new B();我也就不用说了。自己推导即可。
       System.out.println(b.x);
        System.out.println(c.x);
    同样也不想说了。
      

  2.   

    不好意思,下次我会注意的。谢谢你的回答,一下子明白了好多,不过还有几个小问题想请教下,就是一开始为A和B开辟内存空间,是不是当B这个对象生成后,该对象所占用的实际内存空间就是为A和B各自所开空间之和?还有那个动态绑定有什么规则需要遵循的?