型が 2 つのインターフェイスを実装し、各インターフェイスが同一のシグネチャを持つメソッドを定義する場合、実際にはメソッドは 1 つしかなく、それらを区別することはできません。たとえば、2 つのメソッドの戻り値の型が競合している場合、コンパイル エラーになります。これは、継承、メソッドのオーバーライド、隠蔽、および宣言の一般的なルールであり、継承された 2 つのインターフェイス メソッド間だけでなく、インターフェイスとスーパー クラス メソッド間の競合、またはジェネリックの型消去による競合にも適用されます。 .
対応例
次の例では、present() メソッドを持つ (贈り物を贈る) インターフェイス Gift と、同じく present() メソッドを持つインターフェイス Guest (ゲストは出席し、不在ではない) を使用しています。 )。
見栄えのするジョニーは、ギフトとゲストの両方です。
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
@Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
上記のスニペットはコンパイルおよび実行されます。
必要な @Override は 1 つだけであることに注意してください!!!. これは、Gift.present() と Guest.present() が「@Override 相当」であるためです (JLS 8.4.2)。
したがって、johnny には present() の実装が 1 つしかなく、johnny を Gift として扱うか Guest として扱うかに関係なく、呼び出すメソッドは 1 つだけです。
非互換例
以下は、継承された 2 つのメソッドが @Override と同等ではない例です。
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
これは、インターフェイスからメンバーを継承する場合、メンバー宣言の一般的な規則に従わなければならないことをさらに繰り返します。ここでは、Gift と Guest が、互換性のない戻り値の型 (1 つは void、もう 1 つはブール値) で present() を定義しています。1 つの型で void present() と boolean present() を使用できないのと同じ理由で、この例ではコンパイル エラーが発生します。
概要
メソッドのオーバーライドと非表示の通常の要件に従って、@Override と同等のメソッドを継承できます。それらは @Override と同等であるため、事実上、実装するメソッドは 1 つしかないため、区別/選択するものは何もありません。
@Override と同等であると判断されると、それらは同じメソッドになるため、コンパイラはどのメソッドがどのインターフェイス用であるかを識別する必要はありません。
潜在的な非互換性を解決するのは難しい作業かもしれませんが、それはまったく別の問題です。
参考文献
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.8.4