黑马程序员技术交流社区

标题: 子父类构造函数及构造代码块运行疑问? [打印本页]

作者: 聂益飞    时间: 2013-3-13 20:19
标题: 子父类构造函数及构造代码块运行疑问?
本帖最后由 聂益飞 于 2013-3-13 22:44 编辑

class Fu{
   Fu(){
      show();
   }
  
   void show(){
        System.out.println("fu show run");
   }

}

class Zi extends Fu{

   int num = 8;
   {
       System.out.println("cons code num = " + num);
   }

   Zi(){
       System.out.println("cons function num = " + num);
   }

   void show(){

       System.out.println("zi show num = " + num);
   }

}


class Student{

  public static void main(String[] args){
     new Zi();
  }

}
输出结果为:
zi show num = 0
cons code num = 8
cons function num = 8
为什么是这样!我原以为是3个8 这代表了第一个输出的时候未执行num赋值语句。
作者: 朱盛文    时间: 2013-3-13 20:25
本帖最后由 朱盛文 于 2013-3-13 20:44 编辑

class Fu
{
        Fu(){
                show();                        //3,Fu类调用show()方法,因为是在Zi类中加载父类,所以先在Zi类中找show()方法,如果Zi类中没有show()方法,就在Fu类中找。
           }
  
                void show(){
                                 System.out.println("fu show run");
                }

}

class Zi extends Fu{              //2,Zi类继承Fu类,跳到Fu类,加载Fu类的构造函数。

          int num = 8;                      //5,接下来加载Zi类成员变量并初始化,此时num = 8 。
          {                    
                          System.out.println("cons code num = " + num);//6,加载Zi类构造代码块,打印cons code num =8 。构造代码块先于构造函数加载。
          }

              Zi(){
                         System.out.println("cons function num = " + num);//7,加载Zi类构造函数,打印cons function num = 8 。
          }

              void show(){                     //4,调用Zi类的show()方法,此时num还未初始化,所以是默认值  0 ,打印zi show num = 0 。

                 System.out.println("zi show num = " + num);
              }

}


class Student
{

        public static void main(String[] args)
        {
                new Zi();                             //1,创建Zi类对象,加载在堆内存中。
        }

}
所以控制台上打印出来的是:

        zi show num = 0
        cons code num =8
        cons function num = 8


作者: 黑马-郑玉元    时间: 2013-3-13 20:37
构造代码块最先运行,构造代码块存放在静态域,随着类的加载而加载,优先执行!所以第一行输出是zi show num = 0
然后后面的执行过程你知道了吧??
作者: 刘国涛    时间: 2013-3-13 20:51
class Fu{
    Fu(){
       show();//子类覆盖了父类的show方法,所以调用子类的show方法,这时num还没有赋值,默认为0
    }
   
    void show(){
         System.out.println("fu show run");
    }

}

class Zi extends Fu{  

   int num = 8;//如果改成final int num=8;就会输出3个8
    {
        System.out.println("cons code num = " + num);//构造代码块优先于构造函数执行
    }

   Zi(){
        System.out.println("cons function num = " + num);
    }

   void show(){

       System.out.println("zi show num = " + num);
    }

}


class Student{

  public static void main(String[] args){
      new Zi();
   }

}
作者: 樊玲    时间: 2013-3-13 21:10

class Fu{
   Fu(){                                           //3.父类构造函数执行,在执行代码块里边的show()方法时,因为子类继承父类,虚拟机看到子                                                        //类也有show()这个方法,所以就对父类的show()方法,进行了覆盖。因为子类自身还没有实例化。                                            //num依然为0.所以 Zi show num=0
      show();
   }
  
   void show(){
        System.out.println("fu show run");
   }

}

class Zi extends Fu{

   int num = 8;
   {
       System.out.println("cons code num = " + num);
   }

   Zi(){                                                                               // 2. 因为Zi类继承了Fu类。所以子类的构造函数,第一行,默认有super(),去调用
                                                                                       //父类的构造函数,所以就走到了父类的构造函数。便于子类实例化。
       System.out.println("cons function num = " + num);         
   }

   void show(){

       System.out.println("zi show num = " + num);
   }

}


class Student{

  public static void main(String[] args){
     new Zi();                                                  //1.这里,创建对象的时候,首先要找Zi类的构造函数,进行初始化。
  }

}

接下来就是子类自身实例化,就是正常的步骤啦,我就写在这里了,方便看得清楚。
刚刚不是说,调用父类构造函数,是为了子类进行实例化么。所以,父类构造函数执行完,就该子类,执行构造函数了。
这里有一点。有构造代码块的时候,是先于构造函数执行的。所以先执行构造代码块。即:cons code num =8
子类构造函数执行,即cons function num =8。
所以最后执行结果为:
      zi show num = 0
      cons code num =8
      cons function num = 8
作者: 王军行    时间: 2013-3-13 21:45
关键就是覆盖,父类的show方法被子类覆盖了。这里在父类构造函数中调用的已经是子类的方法了
但是java中初始化子类必先初始化父类,父类初始化时子类的num还没有初始化,所以打印出来的是0;

作者: 聂益飞    时间: 2013-3-13 21:55
黑马-郑玉元 发表于 2013-3-13 20:37
构造代码块最先运行,构造代码块存放在静态域,随着类的加载而加载,优先执行!所以第一行输出是zi show nu ...

你确定你说对了?构造代码块中的语句麻烦看清哦!
作者: 黑马-郑玉元    时间: 2013-3-13 22:15
好吧!我错了!!!




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