提問:這道繼承題輸出什麼,大家看題目給答案,不準編譯!

class Depend
{
    int i = 10;
    public Depend()
    {
        print();
        i = 20;
    }

    void print()
    {
        System.out.println("Depend=> " + i);
    }
}


public class Qdb extends Depend
{
    int i = 30;
    public Qdb()
    {
        print();
        super.print();
        i = 40;
    }

    void print()
    {
        System.out.println("Target=> " + i);
    }

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

 

 

 

 

 

 

 

回答:

初始化順序是:

父類成員變量,父類構造函數,子類成員變量,子類構造函數

 

我們順着初始化的順序來說


首先程序從main方法開始執行,new Qdb(),這句話就是要new一個Qdb的對象,根據對象初始化的順序,初始化子類之前必須要初始化父類,所以此時一系列的調用開始了


      1,調用Qdb的父類Depend類的構造函數,在調用構造函數之前,成員變量是先於構造函數初始化的,這個時候Depend裏面的i已經有值了,它的值就是10,在Depend構造函數裏面,我們看到的第一句是:print方法,這個print方法我們要注意,它在Depend的子類也定義了,並且此次初始化是由子類Qdb發起的,所以實際上這個print方法調用的是Qdb裏面定義的print,而這個時候有意思的事情就出現了,此時子類還沒有出生呢,因爲這個時候父類才正在構造之中,所以子類中此時的i還是0,而print正好打印出的是子類的i,所以第一次輸出是0;


      2,父類調用完子類的print後,把父類的i賦了值20,此時父類已經完全被構造出來了,馬上就要開始構造子類了.
     

      3,同理,在調用子類的構造函數之前,子類的i被賦了初值30,然後進入子類的構造函數,此時調用的也是print,這個就非常好理解了,這個print肯定是子類自己的print方法了,此時i已經構造好,當然,此時輸出的值是30;

      4,下一句super.print(),這句話顯示的調用了父類的print方法,而此時父類的i已經在父類的構造函數裏面改爲20了,所以此次調用輸出20.


      5,然後再把子類的i的值設爲50.

在以上過程中,如果掌握好了類的初始化順序,是比較容易知道輸出結果的.還有一點要記住,JAVA裏面的方法是動態綁定的,而成員卻是靜態綁定的.父類裏面調用的print之所以會輸出0,就是因爲print實際上調用的是子類的print,因爲整個這場調用都是由new Qdb()這句話產生的.

 

摘自:http://topic.csdn.net/u/20080619/19/924c55b0-5919-46ad-8bf0-0c6425020253.html?seed=1780906883

 

 

 

執行順序的理解:

class Depend
{
    int i = 10;
    //1.調用父類構造函數
    public Depend()
    {
    	//2.調用了子類的print()方法,父類i = 10
    	print();
    	//4.此處父類i 賦值爲 20
        i = 20;
    }

    //8.由第4步知父類i = 20
    void print()
    {
        System.out.println("Depend=> " + i);
    }
}


public class Qdb extends Depend
{
    int i = 30;
    public Qdb()
    {
    	//5.調用子類print()方法,子類 i = 30;
        print();
        //7.顯示調用父類print()方法
        super.print();
        //9.此處子類i 賦值爲 40
        i = 40;
    }

    void print()
    {
    	//3. 子類i已經被聲明爲int(默認值爲0),未賦值
    	//6. 子類i已經被賦值爲 30
        System.out.println("Target=> " + i);
    }

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


這裏對第3步不理解,如果說i已經被int i = 30;聲明爲int,爲什麼還沒賦值呢?

如果沒被聲明,又爲什麼會輸出 0 呢?

難道說,子類成員變量的聲明在父類構造函數之前,而賦值在父類構造函數之後?

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章