簡體   English   中英

Java中的循環繼承層次結構

[英]Cyclic inheritance hierarchy in Java

我知道Java中不允許使用循環繼承層次結構。 編譯器會拋出錯誤,但我真正感興趣的是知道編譯失敗的確切原因。

class A extends B{}
class B extends C{}
class C extends A{}  // this will give you compile time error.

編譯器拋出錯誤的原因是什么,我編寫代碼class C extends A{}的時刻class C extends A{}

這種關系根本不可能。 它定義了一個無限遞歸類。 為了定義class C ,您需要class A ,定義class A需要class B ,定義class B class C需要class C - 然后返回起點。 這是無限的,所以編譯器不能這樣做,它也沒有邏輯意義。

只看一下extends這個詞,在Java中,一個子類真正擴展了它的超類。 這意味着子對象是它的所有超級對象加上一些新成員和一些指定成員。

怎么可以

  • A是B的延伸
  • B是C的擴展
  • C是A的延伸?

我們可以說擴展是一個順序關系所以: A擴展B意味着A <B (甚至不是A <= B),然后在你的情況下B <C ,所以很明顯C不能小於A.

有一個非常實際的問題(除了在其他答案中解釋的邏輯問題):

必須在實例化期間初始化類。 這是通過首先初始化超類在Java中完成的。 當你有一個循環時,初始化代碼上升到繼承階梯並嘗試初始化從未到達的超類...

因此,對於Java,必須禁止這樣做。

我們可以將問題從C IS-A B減少到這些語句:

class A extends C{}
class C extends A{}

顯然這是一個沖突,因此編譯器會給出錯誤。

讓我們抽象出對家族樹的繼承概念。 從本質上講,這是他們歸結為的。 我將在這里使用反向映射方案,所以我將從C到A工作。

  • 你從母親那里繼承了某些屬性。
  • 你的母親繼承了父親的某些屬性。
  • 你的祖父可以被認為是繼承鏈中最高的。

在Java中,這會導致:

  • C繼承自B.
  • B繼承自A.
  • A是繼承鏈中的最高對象。

采用邏輯極值,這將包括多重繼承 ,這是Java不支持的功能,但可以通過使用接口來緩解。

你的遺產計划所說的是祖父直接從孫子身上繼承,這沒有任何意義。

循環繼承可以有兩個例子:
1. A類擴展A {}: - 這沒有任何意義,因為A類的成員已經存在於A類中,那么為什么要擴展。
2. A類擴展B {},B類擴展A {}: - 在這種情況下,兩個類的成員可以寫在一個類中,然后為什么要編寫兩個類並相互擴展。
由於上述用例無效,因此Java不支持循環繼承。

我以為我會在這個帖子中添加一個尚未說明的Java特定答案。 在Java中,每個類最終都必須從Object類派生。 這就是為什么每個對象都可以毫無問題地轉換為Object實例的原因。 為了支持這一事實, Java繼承教程指出:

Excepting Object,沒有超類,每個類都有一個且只有一個直接超類(單繼承)。 在沒有任何其他顯式超類的情況下,每個類都隱式地是Object的子類。

類可以從派生自類的類派生的類派生,依此類推,最終派生自最頂層的類Object。 據說這樣的類是繼承鏈中延伸回Object的所有類的后代。

如果允許循環繼承依賴,並且因為Java中的類必須只有一個直接超類(參見上文),那么任何循環依賴鏈中的類實例(例如,類ABC實例)都不能從Object ,不允許。 因此,這些循環依賴項對象都不能被視為Object 因此,編譯器必須禁止循環依賴。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM