2017-07-18 69 views
4

我正在學習Java中的內部和外部類。我知道內部和外部類是什麼以及爲什麼使用它們。我在這個話題上遇到了以下問題,但找不到答案。如何定義繼承內部類的子類的構造函數?

假設下面的代碼給出:

class outer{ 
    class inner{ 

    } 
} 

class SubClass extends outer.inner{ 
} 

問:應該如何最小的子類構造函數中定義?爲什麼?

Option 1- 
Subclass() { 
    //reason: bacause the default constructor must always be provided 
} 
Option 2- 
Subclass (Outer outer) { 
    //reason : because creating an instance of **Subclass** requires an instance 
    //of outer, which the **Subclass** instance will be bound to 
} 

Option 3- 
Subclass (Outer outer) { 
    outer.super(); 
    //reason : because creating an instance of **Subclass** requires an explicit 
    //call to the **Outer's** constructor, in order to have an enclosing instance 
    //of **Outer** in scope. 
} 
Option 4- 
Subclass (Outer.inner inner) { 
    //reason : bacause an instance of **inner** is necessary so that there is a 
    //source to copy the derived properties from 
} 

PS。這是一個多選題。只有1回答預計

我是新來的Java,不知道太多關於這些高級的主題

感謝

+0

相信沒有以上的,並認爲這是對一個[接收機參數的情況下 - JLS# 8.4.1](http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.1)。 – EJP

回答

2

下面是從遵循這個相同的邏輯,而是由不流通的JLS爲例但通過直接在構造函數中創建實例:

示例8.8.7.1-1。合格的超類構造函數調用

class Outer { 
    class Inner {} 
} 
class ChildOfInner extends Outer.Inner { 
    ChildOfInner() { (new Outer()).super(); } 
} 

父類的構造調用可細分爲:

  • 不合格的父類的構造調用開頭的關鍵字超 (可能帶有明確的類型參數的開頭)。

  • 合格的超類構造函數調用以主 表達式開頭。

它們允許子類構造函數明確關於 直接超類(§8.1.3)指定新 創建的對象的直接包容實例。當超類 是內部類時,這可能是必需的。

殼體中提出的答案最近的是

public SubClass(Outer outer) { 
    outer.super(); 
} 

要延長Outer.Inner即一個內部類的Outer,​​構造需要具有Outer一個實例,它是封閉類型。

outer.super();將調用Outer父類的構造函數,即Inner構造函數。

outer.super();語法可以是令人不安的,因爲我們沒有關於構造的一個參數,但在延伸的內部類的類的情況下,通常調用super(),子類的構造函數允許此語法。

+0

'outer.super()'不會編譯... –

+0

@Usagi Miyamoto我剛剛嘗試過。有用。 – davidxxx

+0

你的類'Outer'是否有一個名爲'super()'的方法?除非這樣做,'super'是一個保留字(一種語言結構),保留給超類的構造函數的調用,因此不能用類或實例標識符進行限定... –

0

我不認爲,「外部」類可以擴展內部類。這個構造意味着,一個類可以訪問另一個類的私有成員。

不過,您可以有一個內部類來擴展相同外部類的另一個內部類。

至於構造,外實例在實例中指定,而不是作爲一個參數:

class Outer { 
    class Inner { 
     ... 
    } 
    class SubInner { 
     ... 
    } 
    void method() { 
     Inner i = this.new SubInner(); 
    } 
}