実装 - java 多重継承
Java 8では、(デフォルトのメソッドを使って)インタフェースを実装する順序が重要なのはなぜですか? (2)
ご存じのとおり、複数のinterfaces
をJavaで実装することができます。 実装の順序は重要ですか? つまり、 Java 8
B、CはC、Bと同じです。 私のテストは順序が重要であることを示しています - しかし、誰もがこの背後にある論理を説明することができますか?
public interface A {
public default void display() {
System.out.println("Display from A");
}
}
public interface B extends A {
public default void display() {
System.out.println("Display from B");
}
}
public interface C extends A {
public void display();
}
public interface D extends B, C {
}
上記のコードはうまくいきます。 順序B, C
をC, B
に変更すると、エラーが発生しますThe default method display() inherited from B conflicts with another method inherited from C.
public interface D extends C, B {
}
編集する
私はEclipse(Mars)を使っています。 JDK jdk1.8.0_51
。 JRE jre1.8.0_60
。
javacからの結果(すべてのバージョン1.8.0_x):
error: interface D inherits abstract and default for display() from types B and C
ecj 4.4からの結果 :
The default method display() inherited from B conflicts with another method inherited from C
ecj > = 4.4.1からの結果 :
NO ERROR
それでもecj> = 4.4.1は、 D
のextends句の順序が変更された場合にエラーを正しく報告します。
これはEclipseのバグであり、4.4.1で導入されました。 フォローアップするためにバグ477891を提出しました。
編集: バグ477891はMilestone 3でEclipse 4.6に向けて修正されました(GA:2016年6月)。
どちらかの方法でエラーメッセージがあるはずです。 jdk 1.8.0_31を使用すると、インターフェイスの順序に関係なく、次のようなエラーメッセージが表示されます。
ABから継承されたデフォルトのメソッドdisplay()は、ACから継承された他のメソッドと競合します。
解決策は、どのスーパークラスの実装を使用するかをコンパイラに指示するためだけに、 D
display()
をオーバーライドすることです。
public interface D extends B, C {
default void display(){
B.super.display();
}
}
またはdisplay()
abstractを作り直す
interface D extends B, C {
public void display();
}
私よりも新しいバージョンを使用してこのエラーが発生した場合は、バグレポートを送信する価値があるでしょうか。