2014-01-06 126 views
5

我認爲結果可能是'43',因爲q的類型是'poly 1'。然而,結果是'44'。我無法理解這一點。請給我答案。爲什麼這個java程序的結果是'44'?

class poly1 { 
int a; 
public poly1(){ 
    a = 3; 
} 
public void print_a(){ 
    System.out.print(a); 
} 
} 
public class poly2 extends poly1{ 
public poly2(){ 
    a = 4; 
} 

public void print_a(){ 
    System.out.print(a); 
} 

public static void main(String[] args){ 
    poly2 p = new poly2(); 
    p.print_a(); 

    poly1 q = new poly2(); 
    q.print_a(); 
} 

} 

回答

2

當你調用類的構造函數,類超類型構造器是調用第一(直到有沒有超級類型)。

當你調用

new poly2(); 

poly1構造函數首先調用(因爲poly1是一個超級類型的poly2),設置a3,然後poly2構造函數被調用,設置a4這是什麼你看。


q的類型是 '聚1'

什麼似乎混淆你的是,在下面的代碼

poly1 q = new poly2(); 

變量q被聲明爲poly1類型。這在這種情況下沒有任何區別。真正重要的是對象的運行時間類型。這是由new聲明決定的。在這種情況下,該對象是動態類型poly2

1

對不起我剛纔的答覆..顯然,我還沒有看到正確的問題...

public static void main(String[] args){ 
    poly2 p = new poly2(); 
    p.print_a(); 

    poly1 q = new poly2(); 
    q.print_a(); 
} 

現在,當你這樣做:

poly2 p = new poly2(); 

出現以下情況..

  1. 調用poly2構造函數。
  2. poly2構造函數將創建調用轉發給poly1構造函數。
  3. 的值是3(在POLY1構造初始化)
  4. 控制回來一個被設置爲4在POLY2構造POLY2構造

第二種情況也發生同樣的情況。

+0

遺憾。改變了它... – TheLostMind

0

他們POLY2的全部實現,所以他們使用POLY2的結構功能,所以控制檯顯示「44」

2

當你運行這個程序,在

poly2 p = new poly2(); 

一個的值是4,因爲它通過POLY2的構造在

 poly1 q = new poly2(); 

一個值由POLY2的構造函數initalised初始化,再4,所以它會再次輸出4給出「44」的輸出。 每次你創建「p」和「q」時,「a」的值首先由poly1的構造函數初始化,並且「a」的calue由類poly2的構造函數初始化,因爲poly2擴展了poly1類。

嘗試調試代碼,您將會了解程序的確切流程。

根據語言規範,實例變量甚至在進行super()調用之前都不會被初始化。

這些都是在課堂實例創建的構造步執行的步驟/

  • 指定的參數對於構造新創建的參數變量此構造函數調用。

  • 如果此構造函數以相同類中另一個構造函數的顯式構造函數調用(第8.8.7.1節)開頭(使用此參數),則計算參數並使用這五個相同的步驟來遞歸構造函數調用。如果構造函數的調用突然完成,則此過程由於同樣的原因突然完成;否則,請繼續執行步驟5.

  • 此構造函數不是以相同類中另一個構造函數的顯式構造函數調用開始的(使用此方法)。如果此構造函數用於Object以外的類,則此構造函數將以顯式或隱式調用超類構造函數(使用super)開始。評估參數並使用這五個相同的步驟遞歸地處理該超類構造函數的調用。如果構造函數的調用突然完成,那麼出於同樣的原因,此過程會突然完成。否則,請繼續執行步驟4.

  • 執行此類的實例初始值設定項和實例變量初始值設定項,將實例變量初始值設定項的值分配給相應的實例變量,並按文本顯示的從左到右順序在類的源代碼中。如果執行這些初始化程序中的任何一個都會導致異常,則不會執行進一步的初始化程序,並且此過程突然以相同的異常完成。否則,請繼續步驟5.

  • 執行此構造函數的其餘部分。如果該執行突然完成,則此過程因相同原因突然完成。否則,此過程正常完成。

0

通過查看對象來調用方法。在你的情況下,對象是類Poly2,所以在這種情況下它將調用Poly2類的print_a方法。

加成

執行的這裏構造事項。構造函數的執行順序是第一個基類構造函數,然後是派生類構造函數。

+0

的'print_a'方法不影響輸出。 –

+0

執行構造函數的重要位置。構造函數的執行順序是第一個基類的構造函數,然後派生類的構造函數 – eatSleepCode

+0

那麼這應該是你的答案。這與'print_a'方法無關。 –

0

當你運行這個程序,在下面的行

poly2 p = new poly2(); 

一個的值是4,因爲它通過POLY2的構造在下面的線

poly1 q = new poly2(); 

的refrence你是初始化,再創建是poly1但在運行時將對象因此在這一線的價值創造poly2變成4,這就是爲什麼你所得到的結果44

相關問題