package test;
public class Sub extends Super {
int j = 30;
Sub() {
print();
j = 40;
}
void print() {
System.out.print(j);
}
public static void main(String[] args) {
System.out.print(new Sub().j);
}
}
class Super {
int i = 10;
Super() {
print();
i = 20;
}
void print() {
System.out.print(i);
}
}

解决方案 »

  1.   

    有点恶心。
    System.out.print(new Sub().j);
    先执行 new Sub()。
    先声明成员变量 int j = 30;
    到了构造方法。
    Sub() {
    super();//默认会加这一条语句。所以先执行父类构造方法。
    print();
    j = 40;
    }
    父类构造方法。
    Super() {
    print();//由于没执行 i 的 赋值,直接执行构造方法。打印出 i 的默认值 0
    i = 20;//最后父类 i = 20;
    }跳回到子类。
    print();打印出 j 的初始值 30
    j = 40;
    然后回到main 函数 打印出40结果 03040
      

  2.   

    把程序执行顺序标出来了,LZ可以看下public class Sub extends Super {
    int j = 30;//(2) Sub() {
    //super(); //(3)
    print();//(6)
    j = 40;//(8)
    } void print() {
    System.out.print(j);//(7)这时j=30,//(10)此时j=40
    } public static void main(String[] args) {
    System.out.print(new Sub().j);//(1)先执行new Sub(),(9)打印new Sub().j
    }
    }class Super {
    int i = 10; Super() {
    print();//(4)
    i = 20;
    } void print() {
    System.out.print(i);//(5)此时i没有赋值,为默认值0
    }
    }
      

  3.   

    1楼解释有错误:1 程序执行new Sub()时,先给变量j赋默认初值0.(而不是 j=30;)。
    2 父类的print方法被子类覆写了,跳到父类的构造方法时,执行的是子类被覆写的print()方法。
    3 第一个输出是把j(=0)输出了。
    4 父类构造方法执行完后,回到子类,这时先给变量j显示赋值(j=30).
    5 子类构造方法执行,输出30。
    6 最后40好理解。楼主可以把父类构造方法直接输出一个字符串,比如  System.out.println("Hello"); 可以看到根本不执行。
      

  4.   

    “楼主可以把父类构造方法直接输出一个字符串,比如 System.out.println("Hello"); 可以看到根本不执行。”
    抱歉,上面这句话不对, 是在父类的print()方法里,加上一句。(不是在构造方法里。)
      

  5.   

    谢谢!一直栽在父类子类问题上。想问下问什么都执行父类super()方法,还要被子类覆盖,有点蛋疼.赋值问题我表示认同,以前也看到一些资料,声明和赋值不是一起执行的。得到的理念是成员变量是在构造函数中赋值。开始那个0没解释通,就有点想当然了。对楼主表示抱歉。
    那就是赋值的执行过程是这样的?
    int j;//声明
    Sub() {
    super();
    j=30;//赋值
    print();
    j = 40;
    }
    这部分还是要好好研究下。总算定型了,要么那个大神再来讲解下。
    还有那个super();覆盖问题是不是可以理解为直接把父类那段构造方法直接复制下来。比如
    int j;//声明
    Sub() {
    print();
    i = 20;//父类构造方法。
    j=30;//赋值
    print();
    j = 40;
    }
    如果是这样就好理解多了。
      

  6.   

    实际我昨天发帖的时候我做过输出调试,就是想不明白为什么子类覆盖了父类的print()方法,当子类调用super()方法构造实例的时候,在父类的构造方法中为什么会执行子类的print()方法?
      

  7.   

    多态嘛,这个有啥好不理解.  模板方法设计模式里面很多.  LZ多见识就知道了.
    有很多模板方法设计模式是在类里面调用的abstract方法, 而这些方法全是由子类实现的.
      

  8.   

    再告诉LZ一招, 实在弄不明白执行顺序了,  拿javap看下class码
      

  9.   

        为什么j=0啊, int j=30 不是给j赋了初值吗
      

  10.   

       第2步执行子类的print方法输出i的时候,j不是已经有初值30吗?
                为什么在第3步说j=0?
      

  11.   

    http://wenwen.soso.com/z/q191435823.htm
    参考一下上面网址.
      

  12.   

    int j;//声明
    Sub() {
        super();
        j=30;//赋值
        print();
        j = 40;
    }
    这个应该是对的
      

  13.   

    因为当执行父类的构造方法里的print()方法时,这时的引用(this 可以忽略不写)仍然是子类的引用,又因为子类里覆盖了父类的print()方法,所以调的是子类的print()方法.