[英]How does Java inheritance work when inner classes are involved
當存在內部類時,我很難理解繼承在Java中的工作方式。 我目前正在研究子類需要稍微更改其父類內部類功能的東西。 我在下面提出了一個更簡單,類似的示例。
我希望此代碼可以打印“我是ChildClass.InnerClass”,但可以打印“我是ParentClass.InnerClass”。 為什么是這樣? 另外,如果我將main中的obj對象更改為ChildClass類型,則輸出更改為“我是ChildClass.InnerClass”。 為什么是這樣?
通常,建議的改變對象父類內部對象行為的方法是什么?
class InnerClassTest {
//-----------------------------------------------------------------------
// PARENT CLASS
class ParentClass {
public ParentClass() {
x = new InnerClass();
}
InnerClass x;
class InnerClass {
public void speak() {
System.out.println("I am a ParentClass.InnerClass");
}
}
}
//-----------------------------------------------------------------------
// CHILD CLASS
class ChildClass extends ParentClass {
public ChildClass() {
x = new InnerClass();
}
InnerClass x;
class InnerClass extends ParentClass.InnerClass {
public void speak() {
System.out.println("I am a ChildClass.InnerClass");
}
}
}
//-----------------------------------------------------------------------
// MAIN
public static void main(String[] args) {
ParentClass obj = (new InnerClassTest()).new ChildClass();
obj.x.speak();
}
}
變量不像方法那樣“被覆蓋”。
在您的通話中,您希望x
是Child
但這不是因為x
是變量,而不是方法。
但請注意:您的引用類型是ParentClass
因此obj.x
指向ParentClass
的InnerClass
屬性,即使parentClass
背后的實際實例是ChildClass
!
為了顯示您期望的句子,您必須將類型引用更改為ChildClass
:
public static void main(String[] args) {
ChildClass obj = (new InnerClassTest()).new ChildClass();
obj.x.speak();
}
為了更好地理解該概念,請嘗試在ParentClass
和ChildClass
類中都定義一個方法:
public InnerClass getInnerClass(){
return x;
}
並將x
私有。
因此,“替代概念”適用。
在這種情況下,您的最終通話是:
ParentClass obj = (new InnerClassTest()).new ChildClass();
obj.getInnerClass().speak();
要更改內部類的行為,請考慮使用模板方法模式或更好的方法 : 策略模式 (因為更加尊重DIP)
刪除重新聲明
InnerClass x;
來自兒童班。 因此,您只有一個x
並且將在子類的構造函數中重新分配。 表示一個x
(指的是在子ctor中創建的對象)。
它在父類中隱藏了一個。 這就是為什么您最終擁有兩個字段,分別引用兩個不同的對象的原因。 由於存在變量的靜態(編譯時或早期)綁定,
ParentClass obj;
//obj.x means the x in parent
和
ChildClass obj;
//obj.x means the x in child
通常,建議的改變對象父類內部對象行為的方法是什么?
我建議一開始就使用較簡單的設計。 子類應該通過覆蓋其方法來修改其父類的行為,因此我只需添加一些工廠方法newInnerClass()
即可覆蓋此依賴項的創建,並在類層次結構的頂部管理該對象。
這將比您建議的方法更加靈活,因為newInnerClass()
可以實例化定義在任何地方的類,只要它具有正確的接口即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.