黑马程序员技术交流社区

标题: 为什么会是这样的结果呢? [打印本页]

作者: outsider1020    时间: 2014-12-23 10:29
标题: 为什么会是这样的结果呢?
abstract class A{
public A(){
  this.print();
}
public abstract void print();
}
class B extends A{
private int temp=30;
public B(int temp){
  this.temp=temp;
}
public void print(){
  System.out.println("temp="+this.temp);
}
}
public class Demo {
public static void main(String[] args) {
  new B(100);
}
}
返回结果为什么是0呢?求解。。。。。。。。。。。。。。。

作者: Ogre    时间: 2014-12-23 10:29
部分顺序:
默认初始化
super();  调用父类空参构造
A(){};  没有父类,于是对成员顺序初始化,因为没有成员,所以接着运行A里面的默认super();以下的代码
print();  由于print被重写了,所以执行打印语句
然后打印结果temp=0  A(){}的语句也执行完后,A加载完成,加载B
private int temp=30;  对成员顺序初始化,这时temp被显式初始化赋值30,覆盖掉默认初始化的0
B(){}  对成员初始化完成后,继续运行B构造中的super();以下的执行语句
this.temp = temp;  这时,对temp进行构造初始化,赋值100给temp,覆盖掉显式初始化的30

验证:可将new B(100);改成 B b = new B(100); b.print();
第一次打印结果为temp=0,这是默认初始化后的打印结果
第二次打印结果为temp=100,这是b.print();的打印结果



作者: zhaojiajun    时间: 2014-12-23 18:19
代码默认第一行super(),当new B(100)时先调用父类的构造函数,父类的构造函数中调用了print() 方法,会调用子类的print();这时temp指的是子类的temp,temp还没有被赋值,所以打印的是0;然后再调用子类的构造函数
作者: zhaojiajun    时间: 2014-12-23 18:20
当new B(100)时先调用父类的构造函数,父类的构造函数中调用了print() 方法,会调用子类的print();这时temp指的是子类的temp,temp还没有被赋值,所以打印的是0;然后再调用子类的构造函数
作者: wangbiao    时间: 2014-12-23 19:26
我来凑热闹
作者: ben_vs_cong    时间: 2014-12-23 22:36
代码运行是这样的,因为你是B extends A,那么new B(100)时,会执行B的有参构造方法,而B继承A ,那么B的构造方法中第一行都有默认的super(),所以要先执行父类的无参构造(因为子类可能需要父类的数据,所以先执行完父类的构造方法,再运行子类的)。而在这时,B中的变量temp这时是没有进行显示初始化的,所以它现在是temp=0.所以当在父类构造中调用print()时,输出是0.当时我也没有懂,因为当时我也以为temp=30,其实不是的,其实temp是先默认初始化0,然后才显示初始化。所以当时就没有进行显示初始化。
作者: 小徐_y8nUx    时间: 2014-12-24 08:41
学习了!!!
作者: 不落星辰    时间: 2014-12-24 12:49
学习了。。。。
作者: outsider1020    时间: 2014-12-26 09:43
zhaojiajun 发表于 2014-12-23 18:20
当new B(100)时先调用父类的构造函数,父类的构造函数中调用了print() 方法,会调用子类的print();这时t ...

很有道理。。。。。。。
作者: outsider1020    时间: 2014-12-26 09:44
ben_vs_cong 发表于 2014-12-23 22:36
代码运行是这样的,因为你是B extends A,那么new B(100)时,会执行B的有参构造方法,而B继承A ,那么B的 ...

解释的很详细,谢谢了!!!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2