黑马程序员技术交流社区

标题: 语句执行顺序,帮忙理一下 [打印本页]

作者: 杜佳瑞    时间: 2012-7-26 17:30
标题: 语句执行顺序,帮忙理一下
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();
        }
}

作者: 谭培龙    时间: 2012-7-26 18:03
  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:05
本帖最后由 肖琦 于 2012-7-26 18:36 编辑

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

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

QQ截图20120726173944.png

作者: 黑马陈旭东    时间: 2012-7-26 18:09
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 19:01
肖琦 发表于 2012-7-26 18:05
以下是我画的流程图,希望对你有帮助......
刚刚图片做了些修改...

还是有点问题,走构造函数前先初始化成员,那么new Zi()后应该是先走子类的构造函数,这里面第一句话super()才调用父类构造函数,所以也应先初始化子类的成员啊

作者: 杜佳瑞    时间: 2012-7-26 19:03
黑马陈旭东 发表于 2012-7-26 18:09
class Fu
{
        int a = 2;

老师讲过“创建对象在内存的几步”      在哪里有?
作者: 范泰洋    时间: 2012-7-26 19:46
这时注释之前的。
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, 下载次数: 26)

注释的.png





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