5

次のコードを検討してください。

public interface A {
  public A another();
}

public interface B {
  public B another();
}

public interface AB extends A,B {
  public AB another();
}

これにより、 でコンパイル エラーが発生しますAB

タイプ B と A は互換性がありません。どちらも another() を定義していますが、戻り値の型は無関係です

私はこのSOの質問を見て、受け入れられた回答の非互換性の例に従ってください-つまり

public interface C { 
  public void doSomething();
}

public interface D {
  public boolean doSomething();
}

public interface CD extends C,D { 
}

ただし、その場合、戻り値の型はまったく互換性がありませんでした。戻り値の型は void とブール値の両方にすることはできません。一方、上記の例では、 のanother()戻り値の型ABは anAと a の両方Bであるため、両方の拡張インターフェイスを実装できます。

さらに、JLS (8.4.8、8.4.8.3、8.4.8.4) を見ても、上記の例が違法である理由がよくわかりません。誰かが私にこれを説明できますか?

A第二に、またはBの契約要件を繰り返す以外に、これに対する解決策/回避策はありますABか?

4

1 に答える 1

12

このエラー メッセージは、1.5 より前のバージョンの Java で表示されます (少なくとも、Eclipse でコンプライアンス レベルを 1.4 に設定すると、エラーを再現できます)。言い換えれば、十分に古い仕様を見ていることを確認してください。

Java >= 1.5 では、以下は正常にコンパイルされます。

interface A {
    public A another();
}

interface B {
    public B another();
}

interface AB extends A,B {
    public AB another();
}

おっしゃる通り、ABは anAと a の両方なのでB、両方のインターフェースを満たします。


以下は、Java 言語仕様 (Second Edition、つまり Java 1.4) からの引用です。

9.2 インターフェースメンバー

インターフェイスのメンバーは次のとおりです。

  • インターフェイスで宣言されたメンバー。
  • これらのメンバーは直接スーパーインターフェースから継承されました
  • インターフェイスに直接のスーパーインターフェイスがない場合、[...]

したがって、インターフェイスが同じシグネチャで異なる戻り値の型または互換性のない throws 句を持つメソッドを宣言すると、コンパイル時エラーになります。

さらに、現在の仕様は次のように述べています。

9.4.2 オーバーロード

インターフェイスの 2 つのメソッド (両方が同じインターフェイスで宣言されているか、両方がインターフェイスによって継承されているか、または 1 つが宣言され 1 つが継承されているかどうか) が同じ名前であるが、オーバーライドと同等ではない異なるシグネチャを持っている場合 (§8.4.2)、メソッド名はオーバーロードされていると言われています。この事実によって問題が生じることはなく、それ自体がコンパイル時のエラーになることはありません。戻り値の型間、または名前が同じでシグネチャが異なる 2 つのメソッドの throws 句の間には、必要な関係はありません。

于 2012-07-05T11:21:42.547 に答える