実装 - 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, CC, 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();
}

私よりも新しいバージョンを使用してこのエラーが発生した場合は、バグレポートを送信する価値があるでしょうか。





default-method