黑马程序员技术交流社区

标题: 求助:构造函数 [打印本页]

作者: lichao    时间: 2013-11-10 19:10
标题: 求助:构造函数
  1. class Test1
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 A a=new A();
  6.         }
  7. }
  8. class A extends B
  9. {
  10.         int i=5;
  11.         static int j=4;
  12.         A()
  13.         {
  14.                 System.out.println(i);
  15.                 System.out.println(j);

  16.         }
  17.         void m()
  18.         {
  19.         System.out.println("sss"+i);
  20.         System.out.println("sss"+j);
  21.         }
  22. }
  23. class B
  24. {
  25.         B()
  26.         {
  27.         m();
  28.         }
  29.         void m()
  30.         {
  31.         }
  32. }
复制代码
结果为啥是sss0sss4
5
4
求详细解释!!!!!!



作者: 小痞痞    时间: 2013-11-10 19:45
  1. class Test1
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 A a=new A();    //先调用了A的构造函数
  6.         }
  7. }
  8. class A extends B
  9. {
  10.         int i=5;
  11.         static int j=4;
  12.         A()                                                //1
  13.         {
  14.                                 //super();
  15.                                 //显示初始化  i = 5; j = 4
  16.                                 //4
  17.                 System.out.println(i);
  18.                 System.out.println(j);

  19.         }
  20.         void m()        //3
  21.         {
  22.                         //第一次调用还没有进行显示初始化所以i = 0;j = 4;因为j是static的所以一创建就有值了
  23.         System.out.println("sss"+i);
  24.         System.out.println("sss"+j);
  25.         }
  26. }
  27. class B
  28. {
  29.         B()                                        //2
  30.         {
  31.         m();                                //调用的是A类自己的m方法
  32.         }
  33.         void m()
  34.         {
  35.         }
  36. }
复制代码

作者: pireteMrZ    时间: 2013-11-10 19:51
是这样的,因为类A是继承类B的,类B里有m函数,所以在执行时,先执行类A里实现的类B里的m函数,也就是
void m()
        {
        System.out.println("sss"+i);
        System.out.println("sss"+j);
        }
又因为这时候,并没有赋值给i,所以i默认值为0。执行完m函数之后才会执行
int i=5;
        static int j=4;
        A()
        {
                System.out.println(i);
                System.out.println(j);

        }
所以就会出现LZ那样的结果。
  
作者: 青年黨衛軍    时间: 2013-11-10 19:54
首先卤煮需要搞清楚这个程序的执行顺序:
1.main方法中类A创建一个对象需要调用自己的无参构造函数A()。
2.因为为类A是继承自类B的,所以在类A调用自己的构造函数之前JVM先要执行父类B的无参构造函数B()。
3.在B()中有一个父类方法m(),由于类A中已经复写了m()方法,所以父类的m()方法没有执行,转而直接执行子类A中的m()方法。
4.此时类A的构造函数还没有执行,所以变量i还没有写入内存,需要注意的是变量j定义为了静态,这意味着变量j随着main方法一运行就已经写入了内存中的方法区,所以此时变量j完成了赋值的,而变量i此时还没有,默认为0,所以会出现:
  1. sss0
  2. sss4
复制代码
5.之后类A的构造函数被调用,变量i此时被初始化为5,所以输出结果为:
  1. 5
  2. 4
复制代码

作者: lichao    时间: 2013-11-10 20:05
  1. class B
  2. {
  3.         B()                                        //2
  4.         {
  5.         m();                                  //调用的是A类自己的m方法      
  6.         }
  7.         void m()
  8.         {
  9.         }
  10. }
复制代码
为什么调用A类的m方法,而不调用自己的m方法呢????

作者: pireteMrZ    时间: 2013-11-10 20:19
lichao 发表于 2013-11-10 20:05
为什么调用A类的m方法,而不调用自己的m方法呢????

不是调用的A类的m方法,而是,A类是继承自B类,B类的m方法是空的,A类把m方法实现了。在main函数里,是创建了A类的构造函数对象,所以执行A类里的实现的m方法。
作者: 小痞痞    时间: 2013-11-10 20:36
lichao 发表于 2013-11-10 20:05
为什么调用A类的m方法,而不调用自己的m方法呢????

因为你new的是A类对象
非私有方法编译看左边运行看右边
A a = new A();
左边和右边都是A的对象   所以最后运行的是A类的方法
作者: 小痞痞    时间: 2013-11-10 20:38
pireteMrZ 发表于 2013-11-10 20:19
不是调用的A类的m方法,而是,A类是继承自B类,B类的m方法是空的,A类把m方法实现了。在main函数里,是创 ...

:L不调用A类的m方法就不会是哪个结果了       程序最后还是调用的A类的m方法
作者: pireteMrZ    时间: 2013-11-10 21:52
小痞痞 发表于 2013-11-10 20:38
不调用A类的m方法就不会是哪个结果了       程序最后还是调用的A类的m方法 ...

呃...我的意思是不应该称作“调用”A类的m方法,因为创建的就是A类的构造函数对象,所以执行的就是A类的m方法。
作者: lichao    时间: 2013-11-11 19:50
多谢大家了。哈哈。。。。




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