2016-03-04 31 views
11

參考我有三個類使用超()在Java

class WithInner { 
    class Inner {} 
} 

public class InheritInner extends WithInner.Inner 
{ //constructor 
InheritInner(WithInner wi) { 
    wi.super(); 
} 
} 

這個例子是從Eckel的在Java編程思想服用。我不明白爲什麼我們不能撥打wi = new WithInner();而不是.super()?在調用wi.super()時,我們調用Object的默認構造函數,對不對?

+0

奇怪的代碼尚未編譯... – h22

+0

'wi = new WithInner();'會創建一個新的'WithInner'對象,但不會對給定的構造函數做任何事情。 –

+0

@ammoQ否,它將無法編譯。請參閱下面的答案。 – davmac

回答

8

內部類保持對外部實例的引用(例外是static內部類)。在這種情況下,WithInner.Inner實例對包含WithInner實例的引用。這個關聯是在內部類實例化時創建的。

如果不引用外部類,則不能創建內部類的實例。一個擴展這樣的內部類的類也暗含了這樣一個引用,並且需要委託給內部類構造函數來建立關聯。對於這樣做的語法如下所示在你的榜樣:

wi.super(); 

這裏,super()本質上是指父類的構造 - 也就是WithInner.Inner構造。構造函數不正式使用參數,但仍需要對外部實例(類型爲WithInner)的引用。該行作爲一個整體意味着「調用超類的構造函數,並與wi實例關聯」。

比較的語法有明確關聯的內部類的實例:

wi.new WithInner.Inner() 

是的,這也是有效的語法。但是它並不常見(因爲內部類實例通常只能從外部類中創建,並且在這種情況下,關聯是隱式的 - 在這種情況下,不需要顯式提供關聯的語法) 。

具體參考你的問題:

我不明白爲什麼我們不能稱之爲無線=新WithInner();而不是.super()?

這不會將創建的WithInner實例與內部類實例相關聯。你會得到一個編譯時錯誤,因爲你的構造函數不再顯式地調用合成的超類構造函數,並且它不能被隱式調用,因爲它需要用於關聯的外部實例引用。將外部實例引用看作內部類構造函數的隱藏參數可能是最容易的(實際上,這就是它在引擎下實現的方式)。

而在調用wi.super()時,我們調用Object的默認構造函數,不是嗎?

不,您正在調用WithInner.Inner構造函數,它具有用於外部實例引用的「隱藏」參數; wi實質上作爲隱藏參數值傳遞給WithInner.Inner構造函數。

+0

優秀的解釋。希望能夠勸阻任何人故意實施這樣的設計。 – VGR