簡體   English   中英

帶接口的多重繼承歧義

[英]Multiple Inheritance Ambiguity with Interface

我們都知道有關多重遺傳的鑽石問題 -

   A
  / \
 B   C
  \ / 
   D

這個問題描述了D類的模糊情況。 如果A類有一個方法並且B和/或C兩個/都覆蓋了該方法,則D覆蓋哪個版本的方法?

這個問題是否也適用於Java中的接口? 如果沒有,Java接口如何克服這個問題?

菱形問題僅適用於實現繼承(在Java 8之前的所有Java版本中都有extends )。 它不適用於API繼承(在Java 8之前的所有Java版本中implements )。

由於具有匹配類型簽名的接口方法是兼容的,因此如果您繼承兩次相同的方法簽名,則不存在菱形問題:匹配方法簽名只是簡單地合並。 (如果類型簽名不一樣,那么你也沒有鑽石問題。)

在Java 7及更低版本中,繼承實現代碼的唯一方法是使用extends關鍵字,該關鍵字最多只能限制一個父級。 因此,沒有多重實現繼承,並且鑽石問題不存在。

Java 8增加了一個新的皺紋,因為它允許接口具有實現代碼。 當您使用具有匹配簽名的方法實現多個接口時,它仍然可以通過簡單地回退到先前的行為(沒有實現繼承)來逃避鑽石問題。

通過接口添加有關Java8多重繼承的現有答案(也就是Java如何仍然避免鑽石問題):

有三條規則要遵循:

  1. 班級總是勝利 類自己的方法實現優先於接口中的默認方法。

  2. 如果類沒有: 最具體的接口獲勝

在此輸入圖像描述

  1. 如果不是這種情況,繼承類必須顯式聲明它正在使用哪個方法實現(否則它將無法編譯)

在此輸入圖像描述

Java克服了這個問題,即使接口可以有方法的默認實現,因為默認實現是明確的A類中A )或者情境是由某些規則解決的 (當B類或C類覆蓋A類的實現時,見下文)。

當類或接口的超類型提供具有相同簽名的多個默認方法時:

  • 實例方法優於接口默認方法。
  • 已忽略其他候選項的方法將被忽略。 當超類型共享一個共同的祖先時,就會出現這種情況

但是, 如果兩個或多個獨立定義的默認方法沖突 ,或者默認方法與抽象方法沖突,則Java編譯器會產生編譯器錯誤。 必須顯式覆蓋超類型方法 在這種情況下,您可以使用super關鍵字調用任何默認實現。

另請參閱: Java 8的新默認接口模型如何工作(包括菱形,多重繼承和優先級)?

使用Java 8中引入的接口中的默認方法,可能會出現多個繼承相關的問題,有3種情況 -

1-如果實現類重寫默認方法並為默認方法提供自己的功能,則類的方法優先於接口默認方法。

2 - 當類實現兩個接口並且兩者都具有相同的默認方法時,類也不會覆蓋該方法,然后將拋出錯誤。

3 - 如果接口擴展另一個接口並且兩者都具有相同的默認方法,則繼承接口缺省方法優先。

在這里閱讀更多相關信息。

Java不支持多重繼承,因此不會出現鑽石問題。 如果B&C是接口,則接口中沒有實現。 即使B&C覆蓋接口A中的方法(不能是類),方法也會有相同的簽名。 關於使用哪種實現沒有歧義,因為沒有實現。

具有虛擬聲明的接口,它們將沒有實現,因此沒有歧義問題。

暫無
暫無

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

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