[解決済み】同じメソッドを持つクラスで2つのインターフェースを実装する。どのインターフェイスのメソッドがオーバーライドされるか?
質問
同じメソッド名とシグネチャを持つ2つのインタフェースがあります。しかし、単一のクラスによって実装されている場合、コンパイラはどのメソッドがどのインターフェイスのためのものであるかを識別することができますか?
例
interface A{
int f();
}
interface B{
int f();
}
class Test implements A, B{
public static void main(String... args) throws Exception{
}
@Override
public int f() { // from which interface A or B
return 0;
}
}
解決方法は?
ある型が2つのインターフェイスを実装しており、それぞれが
interface
が同じシグネチャを持つメソッドを定義している場合、実質的にメソッドは1つしかなく、区別がつきません。例えば、2つのメソッドの戻り値の型が矛盾する場合、コンパイルエラーになります。これは、継承、メソッドのオーバーライド、隠蔽、宣言の一般的なルールであり、2つの継承されたメソッド間だけでなく、競合の可能性がある場合にも適用されます。
interface
メソッドだけでなく
interface
とスーパー
class
メソッドや、ジェネリックの型消去によるコンフリクトが発生することもあります。
互換性の例
以下は
interface Gift
があり、その中に
present()
メソッド(プレゼントを贈るという意味)と、さらに
interface Guest
も持っています。
present()
メソッド(ゲストは存在し、不在ではない、という意味)を使用します。
Presentable johnny
は
Gift
と
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!!!"
}
}
上記のスニペットは、コンパイルして実行します。
なお
は1つだけです。
@Override
必要です!!!
. これは、以下の理由からです。
Gift.present()
と
Guest.present()
は"です。
@Override
-等価である。
JLS 8.4.2
).
このように
johnny
は1つの実装しかありません。
の
present()
をどのように扱うかは問題ではありません。
johnny
として、または
Gift
または
Guest
の場合、呼び出すべきメソッドは1つだけです。
非互換性の例
以下は、2つの継承されたメソッドが NOT である場合の例です。
@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"
}
を継承していることを再確認しました。
interface
は、メンバー宣言の一般規則に従わなければなりません。ここでは
Gift
と
Guest
定義
present()
は、互換性のない戻り値の型があります。
void
もう一方
boolean
. というのは、同じ理由で
void present()
と
boolean present()
が1つの型に含まれている場合、この例ではコンパイルエラーになります。
概要
というメソッドを継承することができます。
@Override
-と同等です。ただし、メソッドのオーバーライドと隠蔽に関する通常の要件に従います。これらは
ARE
@Override
-が等しい場合、事実上実装する方法は1つだけなので、区別・選択することはできません。
と判断されれば、コンパイラはどのメソッドがどのインターフェースに対応したものかを特定する必要はないのです。
@Override
-等価であれば、同じメソッドです。
非互換性を解決するのは厄介な作業かもしれませんが、それは全く別の問題です。
参考文献
- JLS 8.4.2 メソッドシグネチャ
- JLS 8.4.8 継承、オーバーライド、および隠蔽
- JLS 8.4.8.3 オーバーライドと隠蔽における要求事項
-
JLS 8.4.8.4 オーバーライドに相当するシグネチャを持つメソッドの継承
- オーバーライドと同等のシグネチャを持つ複数のメソッドをクラスが継承することは可能です。
関連
-
[解決済み] JavaでFileFilterを作るには?
-
[解決済み] Application startメソッドで例外が発生する。JavaFx 11
-
[解決済み] 環境変数JAVA_OPTSの使い方を教えてください。
-
[解決済み] Javaでのスキャナが動作しない
-
[解決済み] raw 型のメンバへのアンチェックの呼び出し
-
[解決済み] Eclipseでクラスとそれに対応するファイルの名前を変更する方法は?
-
[解決済み] 文字列の長さに応じて文字列をトリミングする
-
[解決済み] インターフェースと抽象クラス(一般的なOO)
-
[解決済み] Javaにおける例外処理によるパフォーマンスへの影響とは?
-
[解決済み] 拡張メソッドはインターフェースに適用できますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] JavaでFileFilterを作るには?
-
[解決済み] XX:MaxDirectMemorySizeの既定値
-
[解決済み] 警告: コンテキスト初期化中に例外が発生 - 更新の試みはキャンセルされました。
-
[解決済み] javacが「using unchecked or unsafe operations」という警告を出す原因は何ですか?
-
[解決済み] Java の条件付きコンパイル:コードチャンクをコンパイルしないようにするには?
-
[解決済み] javascriptでExpression言語を使うには?
-
[解決済み] 型の不一致:ArrayListからListへの変換ができない
-
[解決済み] 1行目2列目でBEGIN_ARRAYを期待したが、BEGIN_OBJECTだった。
-
[解決済み] IntegerからBigIntegerへの変換
-
[解決済み] x--やx++はここで何をするのですか?