A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杜佳瑞 中级黑马   /  2012-7-26 17:30  /  2458 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

class Fu
{
        int a = 2;
        public void test()
        {
                System.out.println("Fu= " + a);
        }
        Fu()
        {
                this.test();
        }
}
class Zi extends Fu
{
        int a = 3;//这句话注释了结果完全不一样(注释前是0,3 注释后是2,2)想不明白,求解,最好将程序执行顺序列一下!!!{:soso_e183:}
        public void test()
        {
                System.out.println("Zi=" + a);
        }
}
class Demo2
{
        public static void main(String[] args)
        {
                Zi z= new Zi();
                z.test();
        }
}

6 个回复

倒序浏览
  1. class Fu
  2. {
  3.         int a = 2;
  4.         public void test()
  5.         {
  6.                 System.out.println("Fu= " + a);
  7.         }
  8.         Fu()//super()就是运行此代码
  9.         {
  10.                 this.test();//调用test方法,因为test方法被子类复写,所以调用的是子类的方法。
  11.         }
  12. }
  13. class Zi extends Fu
  14. {
  15.                 //super();//省略了调用父类空参数的构造函数。
  16.         int a = 3;//这句话注释了结果完全不一样(注释前是0,3 注释后是2,2)想不明白,求解,最好将程序执行顺序列一下!!!
  17.         public void test()
  18.         {
  19.                 System.out.println("Zi=" + this.a);//这里省略了this,如果子类给a赋值。在第一次调用时没有运行到此代码,所以打印默认值0.
  20.         }
  21. }
  22. class Demo2
  23. {
  24.         public static void main(String[] args)
  25.         {
  26.                 Zi z= new Zi();//创建一个子类对象。
  27.                 z.test();//调用子类的test方法。
  28.         }
  29. }
复制代码
回复 使用道具 举报
本帖最后由 肖琦 于 2012-7-26 18:36 编辑

以下是我画的流程图,希望对你有帮助......
刚刚图片做了些修改...

QQ截图20120726173944.png (69.6 KB, 下载次数: 25)

QQ截图20120726173944.png

点评

太感谢了, 懂了  发表于 2012-7-26 18:54

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
class Fu
{
        int a = 2;
        public void test()
        {
                System.out.println("Fu= " + a);
        }
        Fu()
        {
                this.test();
        }
}
class Zi extends Fu
{
        int a = 3;
        public void test()
        {
                System.out.println("Zi=" + a);
        }
}
class Demo2
{
        public static void main(String[] args)
        {
                Zi z= new Zi();//1:创建子类对象找的父类的构造,你的父类构造有个this.test(),这个this是谁调用就指向谁,那子类调用的就是子类的方法。子类对象在内存创建只是初始化了成员变量,成员变量还没有被赋值。所以变量是0。你要看一下老师讲过的“创建对象在内存的几步才会理解”            
   z.test();//2:那这里就不用讲了,对象创建完了,成员变量也被赋值了,子类找本类的变量答案是3.        }
}
回复 使用道具 举报
肖琦 发表于 2012-7-26 18:05
以下是我画的流程图,希望对你有帮助......
刚刚图片做了些修改...

还是有点问题,走构造函数前先初始化成员,那么new Zi()后应该是先走子类的构造函数,这里面第一句话super()才调用父类构造函数,所以也应先初始化子类的成员啊
回复 使用道具 举报
黑马陈旭东 发表于 2012-7-26 18:09
class Fu
{
        int a = 2;

老师讲过“创建对象在内存的几步”      在哪里有?
回复 使用道具 举报
这时注释之前的。
class Fu
{
        int a = 2;
        public void test()
        {
                System.out.println("Fu= " + a);
        }
        Fu()(3)
        {
                this.test();(4)
        }
}
class Zi extends Fu
{
        int a = 3;//这句话注释了结果完全不一样(注释前是0,3 注释后是2,2)想不明白,求解,最好将程序执行顺序列一下!!!
Zi()//隐式默认构造函数,为了好理解,给你添加上去的。(2)
{
  super()
}

        public void test()(5)
        {
                System.out.println("Zi=" + a);
        }
}
class Demo2
{
        public static void main(String[] args)
        {
                Zi z= new Zi();(1) new一个子类对象,然而zi()后面是空参数的,由于zi类没有定义带参数的构造函数,那么默认的构造
函数就还存在,这时zi()就会去(2)这里的默认构造函数,注意:子类的所有构造函数中的第一行,默认都有一条隐式的语句,就是super().所
以就会去(3)这里调用Fu()类的构造函数,由于父类的构造函数里面是this.test() 这个this的意思就是谁调用它,它就代表谁,现在是zi类在
调用它,所以this就代表了zi类,这时就执行子类的test方法,为什么int a = 3;这里为什么不输出是3呢?因为这时的a在堆内存里的默认初
始化值是0,由于还没有得到初始化,所以输出的a值是0 。最后一步再执行z.test()方法,这时z由于获得了a的地址,所以a的默认初始化值原
本的0就会改变为3.所以输出的结果是0和3.  
                z.test();(6)
        }
}
————————————————————————————————————————————————————————
这时注释之后的。
class Fu
{
        int a = 2;
        public void test()
        {
                System.out.println("Fu= " + a);
        }
        Fu()(3)
        {
                this.test();(4)
        }
}
class Zi extends Fu
{
       //int a = 3;//这句话注释了结果完全不一样(注释前是0,3 注释后是2,2)想不明白,求解,最好将程序执行顺序列一下!!!
Zi()//隐式默认构造函数,为了好理解,给你添加上去的。(2)
{
  super()
}
        public void test()
        {
                System.out.println("Zi=" + a);
        }
}
class Demo2
{
        public static void main(String[] args)
        {
                Zi z= new Zi();(1)//前面的(1)(2)(3)(4)步骤,我就不详细讲了,和上面一样的。由于你把子类的成员变量a给注释了,还
有子类继承了父类,所以子类就去指访问父类的成员变量a。所以最后输出的2和2.
                z.test();
        }
}

没注释的:.png (32.67 KB, 下载次数: 24)

没注释的:.png

注释的.png (36.7 KB, 下载次数: 27)

注释的.png

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马