黑马程序员技术交流社区

标题: 继承中构造函数的初始化问题 [打印本页]

作者: 森仔    时间: 2012-11-24 23:06
标题: 继承中构造函数的初始化问题
本帖最后由 森仔 于 2012-11-25 10:43 编辑

代码如下,过于简单木有注释:
class Test
{                           
        public static void main(String[] args)
        {
                Son s = new Son();
                s.show();
        }
}


class Father
{
        Father()
        {
                super();
                show();
                return;
        }

        void show()
        {
                System.out.println("father show");
        }
}
class Son extends Father
{
        int num = 8;
        Son()
        {
                super();  //当执行到这句代码时,应该去初始化父类了吧?
                System.out.println("Son  初始化了...."+num);
                return;
        }
        void show()
        {
                System.out.println("Son show..."+num);
        }
}

本人以为运行结果为:
father show
Son  初始化了....8
Son show...8
但运行结果却是!!!!

Son show...0
Son  初始化了....8
Son show...8

本人有以下疑惑,望各位大虾详细解答:
当子类初始化的时候调用到父类的空参数构造方法(super();)的同时,正好子类也把父类构造函数中调用到的方法(void show())给重写了,
   这时候子类子类在初始化的时候,调用到父类的构造函数时已经加载了自己的重写?
  还有 就算重写了怎么没把num的值给传进去呢??
  怎么是Son show...0,而不是Son show...8呢??

作者: 张硕    时间: 2012-11-24 23:40
创建对象的执行流程:
1        new通过构造器来开辟内存空间,其中包含了父类子对象的空间;
2        new把这个刚刚创建的对象引用给出构造器,new的工作完成了;
3        构造器(非委派)会先去调用父类构造器;
4        父类构造器先执行显示初始化语句;
5        父类构造器再执行自己的方法体内容,父类构造器工作结束了;
6        回到子类构造器,开始执行显示初始化语句;
7        再执行构造器的方法体内容;
8        返回这个引用,结束。
你的这个执行过程是子类构造器,第一句执行了,super()语句,调用了父类的构造器,而父类的第一句super()语句它对应的父类为object类,也就没什么作用,而show()语句,因为还没有初始化完,只打印创建时的默认值0,然后遇到return返回子类构造器,,然后进行显示初始化,num=8.然后执行子类构造器内语句,Son  初始化了....8,然后调用子类show方法,输出Son show...8
作者: 黑马吕世成    时间: 2012-11-25 09:55
当你new子类时,系统就开始为子类分配好了空间,对成员变量进行默认初始化,此时num为零,。将成员函数加载进内存中。分配完空间之后,该干嘛呢!是进行显示初始化?还是执行构造函数?如果你搞懂了这点我想都好说了。其实这个时候虚拟机回去检查子类的相应(就是你调用的那个)构造器是否存在super或是this调用!有就执行,所以执行super时,num还没有进行显示初始化,所以输出零。。等super执行完就接着执行外部的初始化工作,最后再执行构造器里面的代码,这也是后面为什么出现num为8了。另外一种情况是如果木有就返回来执行构造器外面的初始化工作,这个顺序我就不多说了,你懂的。
作者: 森仔    时间: 2012-11-25 10:42
张硕 发表于 2012-11-24 23:40
创建对象的执行流程:
1        new通过构造器来开辟内存空间,其中包含了父类子对象的空间;
2        new把这个刚刚创建 ...

谢了明白了
作者: 森仔    时间: 2012-11-25 10:42
黑马吕世成 发表于 2012-11-25 09:55
当你new子类时,系统就开始为子类分配好了空间,对成员变量进行默认初始化,此时num为零,。将成员函数加载 ...

谢了,想通了




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