黑马程序员技术交流社区

标题: 有意思的小测试,帮你了解子父类的构造过程。 [打印本页]

作者: 陈淑飞    时间: 2012-7-11 21:13
标题: 有意思的小测试,帮你了解子父类的构造过程。
本帖最后由 陈淑飞 于 2012-7-12 20:45 编辑

不说二说,先发个简短的程序:
----------------------------------------------------------------------------------
public class Fu{
int a = 2;
public void test(){
  System.out.println("Parent instance value is: " + a);
}

public Fu(){
  this.test();
}

public static void main(String[] args){
  Fu f = new Zi();
  f.test();
}
}
class Zi extends Fu{
int a = 3;
public void test(){
  System.out.println("Child instance value is: " + a);
}
}
------------------------------------------------------------------
请问,各位程序执行的结果是什么。 为什么,最好能解释下执行的过程。

请各位不要copy代码运行,先猜想构思下结果。并直接回帖,这样带的疑问去验证。

呵呵。


-----------------------------------------
jvm在进走子类构造函数的 第一条语句:
 super();  ,之前是走到过 int a ; 他只是分配了下内存地址和进行了默认赋值 0。
之后就到父类构造函数中去了。
但从父类构造函数中,回来时。第一步 是给a 进行初始化 a =3。
然后....

作者: 陈淑飞    时间: 2012-7-11 21:14
第一个主题贴啊,自己先顶一下,不能让它沉下去。呵呵。
作者: 黑龙江—刘鹏    时间: 2012-7-11 21:52
我也帮你顶一下 我还没学到这里{:soso__5663373028670280397_3:}
作者: 黑马振鹏    时间: 2012-7-11 21:54
Fu f = new Zi();
f.test();

f.test()调用的是ZI的test,这个肯定没问题吧:打印Child instance value is: 3
楼主的问题肯定是 Fu f = new Zi(); 为什么打印Child instance value is: 0
Child instance value is 打印这个是因为调用的其实是子类的方法,
a的值为零,这个我也不是太清楚,


作者: 曹恒业    时间: 2012-7-11 22:06
public class Fu
{
        int a = 2;
        public void test()
        {
                System.out.println("Parent instance value is: " + a);
        }

        public Fu()
        {
                this.test();
        }

        public static void main(String[] args)
        {
                Fu f = new Zi();
                f.test();
        }
}

class Zi extends Fu
{
        int a = 3;
        public void test()
        {
                System.out.println("Child instance value is: " + a);
        }
}

输出结果如下所示,和我猜想的一样。
==============================
Child instance value is: 0
Child instance value is: 3
=======================
下面按楼主要求,说下运行过程和出现的原理。
1.Fu f = new Zi();
JVM读完该行代码,先加载Fu和Zi类,由于都没有静态代码块,构造代码块,所以开始执行父类Fu的构造函数,该函数调用了子类Zi的test()方法,此时子类Zi中的非静态成员变量还没有显示初始化,所以a的值是一开始在堆内存中建立时的默认值0,之后显示初始化子类Zi的成员变量a的值为3,之后运行子类Zi的默认无参构造函数。这个语句执行完毕。

2.f.test();
执行输出语句。
=============================







作者: 封明川    时间: 2012-7-11 22:58
ZI继承了FU,不是有两个主函数了吗,不知道能不能执行?
作者: 黑马振鹏    时间: 2012-7-11 23:38
啸傲江湖007 发表于 2012-7-11 21:54
Fu f = new Zi();
f.test();

看了楼下的答案自己也明白了,稍微调试了代码进行了验证。
把父类的成员变量删掉,把f.test()注释 再运行就明白了流程:
public class Fu{
       
        public void test(){
          System.out.println("Parent instance value is: " );
        }
       
        public Fu(){
          this.test();
        }
       
        public static void main(String[] args){
          Fu f = new Zi();
     //        f.test();
        }
}
class Zi extends Fu{
        int a = 3;
        public void test(){
          System.out.println("Child instance value is: " + (Integer)a);
        }
}

输出:Child instance value is: 0  
并且这个0 是子类中的a的默认值,在没有赋值之前为零。所以打印出结果为零。




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