2011-12-09 46 views
8

在以下示例中被覆蓋的方法,包括:調用從一個構造

class Base {  
    int x=10; 

    Base() {  
     show(); 
    } 

    void show() { 
     System.out.print ("Base Show " +x + " "); 
    } 
} 

class Child extends Base { 
    int x=20; 

    Child() { 
     show(); 
    } 

    void show() {  
     System.out.print("Child Show " + x +" ") ; 
    } 

    public static void main(String s[ ]) { 
     Base obj = new Child(); 
    } 
} 
  • 爲什麼是如下所示
Child Show 0 Child Show 20 
  • 我想構造可以將輸出只有一次訪問實例成員的超級構造函數已完成。

我認爲這裏發生的事情是超級構造函數調用孩子的show()方法,因爲這個方法在Child中被覆蓋。因爲它已被覆蓋,但爲什麼是x 0的值,爲什麼它能夠在超級構造函數完成之前訪問此方法?

+0

正在建設的對象的過程中啓用了虛擬處理機制?我懷疑它不是。 – Mahesh

+0

在C++中,這會導致崩潰。 –

+3

有效的Java是一個很好的Java資源,它非常詳細地介紹了這一點。從項目17:「***構造函數不得直接或間接地調用可重寫方法**(...)如果重寫方法依賴於子類構造函數執行的任何初始化,則該方法不會按預期行爲。 *「如果你手頭有書,我強烈建議閱讀這個項目。 –

回答

11

我認爲這裏發生的事情是超級構造函數調用孩子的show()方法,因爲此方法在Child中被重寫。

這是正確的

但爲什麼是X 0

的價值,因爲它尚未初始化(X兒童)

,爲什麼它能夠在超級構造函數完成之前訪問此方法?

這正是爲什麼在構造函數中,你永遠不應該調用一個方法,它可以被覆蓋(非最終的公共和保護)。

編輯:

這裏奇怪的是,任何事物都有默認/包私有可見。這可能會產生一些奇怪的效果。請參閱:http://www.cooljeff.co.uk/2009/05/03/the-subtleties-of-overriding-package-private-methods/

我建議避免用默認可見性重寫方法(如果可能,可以通過聲明它們來防止這種方法)。

+1

+1序列是主 - > Child() - > Base() - > Child.show()[x尚未初始化] - > Base.show()[以Base.x = 20開頭] – stacker

+0

不,序列是main - > Base() - > Child.show()[x尚未初始化] - > Child()[Child.x = 20] - > Child.show() – Puce

+0

在Child類中的變量x Object類已完成時,默認值爲0嗎?因爲據我記憶,這裏是序列:new Child() - > Base() - > Object - > Child的實現show()... – anathema

6

您還可以從構造重寫的方法,但它的,你不應該。你說明了這樣做的原因:派生類沒有機會獲得初始化,因此將使用未初始化的字段 - 在您的示例中,int x的默認值爲0,這就是爲什麼它正在打印0

相關問題