我是初学者,今天遇到以下问题十分费解,希望各位大侠帮帮忙,谢谢各位class Base {
private int base = 10; public Base() {
test(base);
System.out.println(base);
}
void test(int base) {
++this.base;
System.out.println("superclass");
}
}
public class Child extends Base {
private int child = 20;
public Child() {
test(child);
System.out.println(child);
}
void test(int child) {
--this.child;
System.out.println(this.child);
System.out.println("subclass");
}
public static void main(String[] args) {
new Child();
}
}以上代码的运行结果是:
-1
subclass
10
19
subclass
19问题:-1怎么来的?为什么打印出19呢?代码是如何运行的呀,求完整运行过程

解决方案 »

  1.   

    程序先执行初始化Base的域,然后执行Base的构造函数。
    再初始化Child的域,然后执行Child的构造函数。你这个问题里,Base的test执行的时候,由于继承的存在,执行的是Sub的Test。而此时child还未被初始化,因此使用默认值0,--就是-1。等执行到初始化Sub域的时候,child重新初始化为20,再执行Child的构造函数中的test,--就是19.可以用Eclipse 跟踪调试看看。PS:构造函数中尽量不要调用普通函数,因为此时程序初始化还未完成, 可能出现不可预知的情况。
      

  2.   

    刚才debug了一下,在Child 类里面根本不会执行父类的test() 方法,因为这个方法已经在子类被重写了。因为child不是static,所以在执行构建child的时候child = 0, 再减去一就是-1了,如果改成private static int child = 20,那就是19了
      

  3.   

    2。对象的创建(creation of new class instances),稍微有点烦琐,具体的步骤如下
    (a) 所有的成员变量—包括该类,及它的父类中的成员变量--被分配内存空间,并赋予默认值。(Btw,这里是第一次初始化成员变量)
    (b) 为所调用的构造函数初始化其参数变量。(如果有参数)
    (c) 如果在构造函数中用this 调用了同类中的其他构造函数,则按照步骤(b)~(f)去处理被调用到的构造函数。
    (d) 如果在构造函数中用super调用了其父类的构造函数,则按照步骤(b)~(f)去处理被调用到的父类构造函数。
    (e) 按照书写顺序,执行instance initializer 和 instance variable initializer来初始化成员变量。(Btw,这里是第二次初始化成员变量)
    (f) 按照书写顺序,执行constructor的其余部分。你的-1,就是 --this.Child的时候的,在开始调用构造函数,只是赋值为默认值 0.这个时候还没有赋值 20;
    接下来的 19,自然也懂了吧
      

  4.   

    由于Child继承自Base,所以当执行new Child();的时候,会首先调用基类Base的构造函数:
         public Base() {
        test(base);
        System.out.println(base);
        }
    在执行到test(base);时,会执行:private int base = 10;对base变量进行初始化;
    由于Child的test()方法覆盖了父类Basetest()方法;所以test(base)是调用的Child中test方法;
        void test(int child) {
       --this.child;
       System.out.println(this.child);
       System.out.println("subclass");
       }
    然后有一处容易搞错的地方就是:--this.child,这里的this.child是Child类的成员变量child,而不是参数child,这个时候变量child还没有进行初始化,默认值为0;所以--this.child值为0;如果这里是--child,而不是this.chid,参数child会接收test(base)的base参数值,System.out.println(child);的值就是9。
    后边的就跟2楼哥们说的一样了。
      

  5.   

    主要是子类的test覆盖了父类的test方法。当执行父类构造方法中的test方法,是调用了子类中的test方法。测试child还没有赋值,为0.所以--child==-1了。19是当子类进行调用--child时,child已经赋值为20了。