web-dev-qa-db-ja.com

インターフェースによる多重継承のあいまいさ

私たちは皆、多重継承に関して ダイヤモンドの問題 について知っています-

   A
  / \
 B   C
  \ / 
   D

この問題は、クラスDのあいまいな状況を説明しています。クラスAにメソッドがあり、BCの両方またはいずれかがメソッドをオーバーライドする場合、どのバージョンのメソッドがDをオーバーライドしますか?

この問題はJavaのインターフェースにも当てはまりますか?そうでない場合、どのようにJavaインターフェースがこの問題を克服しますか?

24
Razib

ひし形の問題は実装継承(extends Java以前のJava 8)のみ)にのみ適用されます。[〜#〜] api [〜#〜]継承(implements Java以前の= Java 8)。

タイプシグネチャが一致するインターフェースメソッドは互換性があるため、同じメソッドシグネチャを2回継承しても、ダイアモンドの問題はありません。一致するメソッドシグネチャは、代わりに単に合体します。 (そして、型シグネチャが同じでなければ、ひし形の問題もありません。)

Java 7以下では、implementationコードを継承する唯一の方法は、extendsキーワードを使用することでしたが、これは最大で1つの親に制限されています。多重実装継承ではなく、ひし形の問題は存在しません。

Java 8では、インターフェースに実装コードを含めることができるため、新しいしわが追加されています。一致するシグネチャを持つメソッドを持つ複数のインターフェースを実装する場合、以前の動作(実装の継承なし)にフォールバックするだけで、ひし形の問題を回避できます。

20
Daniel Pryden

インターフェースによるJava8の多重継承に関する既存の回答に追加するには(別名:Javaでもダイヤモンドの問題を回避できます):

従うべき3つのルールがあります。

  1. クラスは常に勝ちます。クラス独自のメソッド実装は、インターフェイスのデフォルトメソッドよりも優先されます。

  2. クラスに何もない場合:最も特定のインターフェースが優先されます

enter image description here

  1. 上記が当てはまらない場合、継承するクラスは、使用しているメソッド実装を明示的に状態にする必要があります(それ以外の場合はコンパイルされません)

enter image description here

7
Andrejs

デフォルトの実装はunambiguous(クラスAの1つ)または状況はいくつかのルールによって解決されます(クラスBまたはクラスCがクラスAからの実装をオーバーライドする場合、以下を参照)。

クラスまたはインターフェイスのスーパータイプが、同じシグネチャを持つ複数のデフォルトメソッドを提供する場合:

  • インスタンスメソッドは、インターフェイスのデフォルトメソッドよりも優先されます。
  • 他の候補によってすでにオーバーライドされているメソッドは無視されます。 この状況は、スーパータイプが共通の祖先を共有する場合に発生する可能性があります

ただし、2つ以上の独立して定義されたデフォルトメソッドが競合する場合、またはデフォルトメソッドが抽象メソッドと競合する場合、Javaコンパイラはコンパイラを生成します。エラーは、スーパータイプメソッドを明示的にオーバーライドする必要があります。この場合、superキーワードを使用して、デフォルト実装のいずれかを呼び出すことができます。

参照: Java 8 '新しいデフォルトのインターフェースモデルはどのように機能しますか(ダイヤモンド、多重継承、優先順位を含む)?

3
olovb

Java 8で導入されたインターフェースのデフォルトメソッドでは、多重継承に関連する問題が発生する可能性があります。3つのシナリオがあります-

1-実装クラスがデフォルトメソッドをオーバーライドし、デフォルトメソッドに独自の機能を提供する場合、クラスのメソッドはインターフェースのデフォルトメソッドよりも優先されます。

2-クラスが両方のインターフェイスを実装し、両方に同じデフォルトのメソッドがある場合、クラスはそのメソッドをオーバーライドしていないため、エラーがスローされます。

3-インターフェイスが別のインターフェイスを拡張し、両方に同じデフォルトメソッドがある場合、継承するインターフェイスのデフォルトメソッドが優先されます。

それについてもっと読む ここ

3
infoj

Javaは多重継承をサポートしていないため、ひし形の問題は発生しません。 B&Cがインターフェースの場合、インターフェースには実装がありません。 BとCがインターフェースAのメソッドをオーバーライドしても(クラスにすることはできません)、メソッドは同じ署名を持ちます。実装がないため、どの実装を使用するかについてのあいまいさはありません。

2
vinay

ダミー宣言を持つインターフェースには実装がないため、あいまいさの問題はありません。

0
SumataPatil