怎樣繼承一個內部類
阿新 • • 發佈:2018-12-26
定義一個內部類時,這個內部類會有一個隱式引用(implicit reference)指向外部類的例項。例如下面的程式碼:
class WithInner {
class Inner {}
}
其實,內部類Inner
預設會有一個帶引數的建構函式,我們通過反射來看一下。
輸出結果為:import java.lang.reflect.Constructor; import java.lang.reflect.Field; class WithInner { class Inner { public void getConstructors() { for (Constructor<?> cons : getClass().getDeclaredConstructors()) { StringBuilder sb = new StringBuilder(); sb.append("constructor: ").append(cons.getName()).append("("); for (Class<?> param : cons.getParameterTypes()) { sb.append(param.getSimpleName()).append(", "); } if (sb.charAt(sb.length() - 1) == ' ') { sb.replace(sb.length() - 2, sb.length(), ")"); } else { sb.append(')'); } System.out.println(sb); } } } } public class InheritInner { public static void main(String[] args) { WithInner wi = new WithInner(); WithInner.Inner i = wi.new Inner(); i.getConstructors(); } }
constructor: WithInner$Inner(WithInner)
從結果可以看出引數的型別就是就是外部類(outer class),也就是說,構造內部類的時候,必須要給它一個外部類的引用。接下來我們讓
InheritInner
繼承WithInner.Inner
。
class WithInner {
class Inner {}
}
public class InheritInner extends WithInner.Inner {
public static void main(String[] args) {
}
}
無法通過編譯:
InheritInner.java:5: an enclosing instance that contains WithInner.Inner is required public class InheritInner extends WithInner.Inner { ^ 1 error
報錯資訊提示我們InheritInner
需要一個WithInner
例項。
那我們給InheritInner
加上我們反射出的帶引數的建構函式。照樣編譯通不過,而且會報同樣的錯誤。這是因為語法規定:在繼承內部類的時候,在建構函式中必須要新增enclosingClassReference.super()
。
class WithInner { class Inner {} } public class InheritInner extends WithInner.Inner { public InheritInner(WithInner wi) { wi.super(); } public static void main(String[] args) { WithInner wi = new WithInner(); InheritInner ii = new InheritInner(wi); } }
OK,編譯通過,執行也正常。但是為什麼要這麼做,我現在也不是很清楚。
參考資料
- Thinking In Java