2013-07-17 114 views
4

當我經歷this文章,下部分私有成員在一個超,我看到了這條線繼承的嵌套類到子類

嵌套類訪問其封閉的所有私有成員 類 - 這兩個字段和方法。因此,由子類繼承的公共或受保護的嵌套類可間接訪問超類的所有私有成員。

我的問題是我們如何能夠直接訪問NestedBaseDerived(就像我們可以訪問任何publicprotected領域)?

如果有一種方法,怎麼能Derived訪問p這是Base私人領域通過Nested

public class Base { 

    protected int f; 
    private int p; 

    public class Nested { 

     public int getP() { 
      return p; 
     } 
    } 
} 

class Derived extends Base { 

    public void newMethod() { 
     System.out.println(f); // i understand inheriting protected field 

     // how to access the inherited Nested class here? and if accessed how to retrieve 'p' ? 
    } 

} 

在此感謝您的時間和精力!

回答

3
Base.Nested theClassBro= new Base.Nested(); 

或者派生類,這應該工作:

Derived.Nested theClassBro= new Derived.Nested(); 

我不知道,如果你需要使用super關鍵字或不

+3

注意'Nested'取決於'實例Base',這就是爲什麼'Nested'的一個實例可以訪問'Base'的東西。 'Base'實例化隱含在'new Base.Nested()'上。 I. e。你可以這樣寫: 'Base myBase = new Base(); Base.Nested theClassBro = myBase.new嵌套();' –

1

非靜態內部類總是需要一個嵌套類的封閉實例。在Base Base或Derived類中定義的代碼(因爲它繼承了內部類),您可以簡單地編寫

Nested nested = new Nested(); 

創建一個新實例。然後,您可以調用Nested引用上的getP()方法來獲取私有p值的值。該值是封裝了Nested實例的Base類實例的一部分。

因爲內部類是公共的,所以在Base或Derived之外定義的代碼也可以創建一個實例。但是這需要一個Derived或Base的封閉實例。對於這種情況,Java在包含類的實例上調用new運算符時有特殊的語法。因此,基地外或派生,你可以這樣做:

Base base = new Base(); 
Base.Nested baseNested = base.new Nested();  
Derived derived = new Derived(); 
Derived.Nested derivedNested = derived.new Nested(); 
Base.Nested d = derivedNested; 

它也可以導入Base.Nested,這樣你可以寫:

Base base = new Base(); 
Nested baseNested = base.new Nested(); 
Derived derived = new Derived(); 
Nested derivedNested = derived.new Nested(); // Base.Nested reference 

這是很好的瞭解這個語法,但我覺得代碼如果只允許封閉類創建內部類的新實例,它通常更清晰(更容易理解,更好的封裝)。如果您需要一個邏輯上僅屬於Base但不需要封閉實例的類,則還可以使用靜態嵌套類。

0

如您所知,Nested只能在包含Nested類定義的類的封閉實例時創建,在我們的例子中爲Enclosing類。爲了能夠通過繼承Nested類來訪問Enclosing類的私有成員,我們需要向Derived類的構造函數提供包含Enclosing.Nested的封閉實例。下面的代碼應該讓它更清楚地理解。我從你原來的例子改變的變量和類的名稱爲更好地理解:


public class Enclosing { 

    protected int protectedMember = 3; 
    private int privateMember = 7; 

    public class Nested { 

     public int getPrivate() { 
      return privateMember; 
     } 

     public int getProtected() { 
      return protectedMember; 
     } 

    } 

} 

class Derived extends Enclosing.Nested { 

    //Provide the enclosing instance that contains Enclosing.Nested 
    public Derived() { 
     new Enclosing().super(); 
    } 

    //Access protected member of Enclosing class 
    public void accessProtectedMember() { 
     System.out.println(getProtected()); 
    } 

    //Access private Member of Enclosing class 
    public void accessPrivateMember() { 
     System.out.println(getPrivate()); 
    } 

} 

public class Test { 
    public static void main(String... args) { 
     Derived derived = new Derived(); 
     derived.accessProtectedMember(); 
     derived.accessPrivateMember(); 
    } 
}