クラスが複数のインターフェイスを実装する場合、両方のインターフェイスが実装されている場合に、コンパイラーがどのメソッドをオーバーライドするかをどのように識別するかという問題が発生します。インターフェイスは、同一のシグネチャを持つメソッドを宣言します。これを詳しく調べるために、提供されたコード例を分析してみましょう:
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; } }
このシナリオでは、コンパイラーは最初にインターフェイス A と B を調べます。これらは両方ともメソッドを定義しているためです。同じシグネチャを持つ場合、それらは実装内の単一のメソッドを効果的に表します。これらは @Override と同等 (JLS 8.4.2) とみなされるため、コンパイラーはそれらを区別する必要はありません。
コンパイラーがクラス Test の実装に到達すると、クラス上で @Override アノテーションが検出されます。 f メソッド。このメソッドがスーパークラスまたはインターフェイスから継承されたメソッドをオーバーライドすることを示します。 A と B の両方が f を宣言しているため、コンパイラはメソッド シグネチャの競合をチェックします。この場合、シグネチャが同一であるため、競合はありません。
したがって、Test で定義された f メソッドは、インターフェイス A と B の組み合わせから継承された単一のメソッド f をオーバーライドします。これは、コンパイラが次のように処理することを意味します。両方の継承されたメソッドの代替としての実装。
一般に、複数のインターフェイスを実装すると、 @Override と同等のメソッドはコンパイル中に問題を引き起こしません。ただし、継承されたメソッドの戻り値の型が異なる場合、またはスーパークラス内のメソッドと競合する場合は、非互換性が発生する可能性があります。
次の例を考えてみましょう。
interface Gift { void present(); } interface Guest { boolean present(); } interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
この場合、コンパイルは失敗します。継承されたメソッド present() の戻り値の型に互換性がないためです。コンパイラはこの競合を解決できず、メソッドに互換性がないことを示すエラーを生成します。
@Override と同等のメソッドを使用して複数のインターフェイスを実装する場合、コンパイラはそれらの結合に基づいてメソッドを識別します。これにより、両方のインターフェイスのメソッドが効果的にマージされます。このプロセスにより、そのようなシナリオでクリーンで明確なメソッドのオーバーライドが可能になります。
以上が同じシグネチャを持つ複数のインターフェイスを実装する場合、Java コンパイラはメソッド オーバーライドの競合をどのように解決しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。