內部類的繼承從而實現對父類的private欄位的引用
阿新 • • 發佈:2018-12-26
子類
public class SubClass extends SuperClass.InnerClass { SuperClass superClass; public SubClass (SuperClass superClass){ superClass.super(); //由於內部類構建器必須同封裝類物件的一個控制代碼聯絡到一起, //所以從一個內部類繼承的時候這裡建立一個控制代碼 this.superClass = superClass; } public void show(){ System.out.println(this.returnPrivates()); } }
父類: 有一個private 的欄位privates
public class SuperClass {
private String privates = "know by Super itsself";
public class InnerClass {
public String returnPrivates(){
return privates;
}
}
}
測試類:
public class Test { public static void main(String[] args) { SubClass sub = new SubClass (new SuperClass()); sub.show(); } }
從內部類繼承 由於內部類構建器必須同封裝類物件的一個控制代碼聯絡到一起,所以從一個內部類繼承的時候,情況會稍微變得有些複雜。這兒的問題是封裝類的“祕密”控制代碼必須獲得初始化,而且在衍生類中不再有一個預設的物件可以連線。解決這個問題的辦法是採用一種特殊的語法,明確建立這種關聯: //: InheritInner.java// Inheriting an inner classclass WithInner { class Inner {}}public class InheritInner extends WithInner.Inner { //! InheritInner() {} // Won't compile InheritInner(WithInner wi) { wi.super(); } public static void main(String[] args) { WithInner wi = new WithInner(); InheritInner ii = new InheritInner(wi); }} ///:~ 從中可以看到,InheritInner只對內部類進行了擴充套件,沒有擴充套件外部類。但在需要建立一個構建器的時候,預設物件已經沒有意義,我們不能只是傳遞封裝物件的一個控制代碼。此外,必須在構建器中採用下述語法: enclosingClassHandle.super(); 它提供了必要的控制代碼,以便程式正確編譯。 7.6.7 內部類可以覆蓋嗎? 若建立一個內部類,然後從封裝類繼承,並重新定義內部類,那麼會出現什麼情況呢?也就是說,我們有可能覆蓋一個內部類嗎?這看起來似乎是一個非常有用的概念,但“覆蓋”一個內部類——好象它是外部類的另一個方法——這一概念實際不能做任何事情: //: BigEgg.java// An inner class cannot be overriden // like a methodclass Egg { protected class Yolk { public Yolk() { System.out.println("Egg.Yolk()"); } } private Yolk y; public Egg() { System.out.println("New Egg()"); y = new Yolk(); }}public class BigEgg extends Egg { public class Yolk { public Yolk() { System.out.println("BigEgg.Yolk()"); } } public static void main(String[] args) { new BigEgg(); }} ///:~ 預設構建器是由編譯器自動合成的,而且會呼叫基礎類的預設構建器。大家或許會認為由於準備建立一個BigEgg,所以會使用Yolk的“被覆蓋”版本。但實際情況並非如此。輸出如下: New Egg() Egg.Yolk() 這個例子簡單地揭示出當我們從外部類繼承的時候,沒有任何額外的內部類繼續下去。然而,仍然有可能“明確”地從內部類繼承: //: BigEgg2.java// Proper inheritance of an inner classclass Egg2 { protected class Yolk { public Yolk() { System.out.println("Egg2.Yolk()"); } public void f() { System.out.println("Egg2.Yolk.f()"); } } private Yolk y = new Yolk(); public Egg2() { System.out.println("New Egg2()"); } public void insertYolk(Yolk yy) { y = yy; } public void g() { y.f(); }}public class BigEgg2 extends Egg2 { public class Yolk extends Egg2.Yolk { public Yolk() { System.out.println("BigEgg2.Yolk()"); } public void f() { System.out.println("BigEgg2.Yolk.f()"); } } public BigEgg2() { insertYolk(new Yolk()); } public static void main(String[] args) { Egg2 e2 = new BigEgg2(); e2.g(); }} ///:~ 現在,BigEgg2.Yolk明確地擴充套件了Egg2.Yolk,而且覆蓋了它的方法。方法insertYolk()允許BigEgg2將它自己的某個Yolk物件上溯造型至Egg2的y控制代碼。所以當g()呼叫y.f()的時候,就會使用f()被覆蓋版本。輸出結果如下: Egg2.Yolk() New Egg2() Egg2.Yolk() BigEgg2.Yolk() BigEgg2.Yolk.f() 對Egg2.Yolk()的第二個呼叫是BigEgg2.Yolk構建器的基礎類構建器呼叫。呼叫 g()的時候,可發現使用的是f()的被覆蓋版本。