9

これは、Javaで複数のインターフェースの継承を使用する例であり、問​​題があります。

なぜ問題があるのか​​を完全に理解していることに注意してください。これは私の質問のポイントではありません。問題は、この特定の複数のインターフェイスの継承のあいまいさについて、名前がある場合にどのように名前を付けるかについてです。

たとえば、C ++では、複数の実装継承を使用し、どのオーバーライドされたメソッドを使用するかを決定できない場合に発生するあいまいさは、「菱形継承問題」と呼ばれます。

http://en.wikipedia.org/wiki/Diamond_problem

繰り返しになりますが、これはここでは同じ問題ではないことを私は知っています。それは重要ではありません。重要なのは、その前のケースでは名前が造られているということです。

そして、これから説明する問題の名前が存在するかどうかを知りたいのですが。

別の種類の多重継承の例を次に示します。ここでは、1つのインターフェイスが、互換性のないメソッドの戻り型を持つ他の2つのインターフェイスから継承します。

interface A {
  void a();
  Integer c();
}

interface B {
  void b();
  Long c();
}

interface MI extends A, B {...}

(「extends」キーワードを使用して、複数のインターフェースの継承が機能していることに注意してください)

次の理由で、それを行うことはできません。

タイプAとタイプBは互換性がありません。どちらもc()を定義しますが、関連のない戻り型を使用します

その状況を説明するために名前が造られましたか?

4

7 に答える 7

3

特定の名前があるかどうかはわかりませんが、少なくともあまり一般的に使用されていないようです。これは、インターフェイスメソッドからクラスメソッドへの暗黙的なマッピングの「単なる」問題です。リターンタイプのみが異なるオーバーロードが発生する可能性がある場合も、問題はありません。したがって、それは署名/オーバーロード/暗黙的なメソッドマッピングの問題に帰着します。

「ThinkinginJava」のオンラインブックにも、その名前はありません。 http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ310_001.htm

ちなみに、C#では、この問題に対処する明示的なインターフェイスの実装が可能です。

于 2010-02-14T17:25:51.103 に答える
3

JLS§6.4.4、インターフェイスタイプのメンバーは、そのような重複するスーパーインターフェイスメンバーをあいまいに呼び出し、コンパイル時エラーを必要とします。Beaujolais Effect Heisenbugなどのカラフルなものを期待していました。多分二人の群衆

于 2010-02-14T18:21:15.403 に答える
2

また、この問題の具体的な名前もわかりません。それが発生したときはいつでも、ある時点で「 returntypeincompatibility」という単語を含む文で説明されていました。これは、Javaクラスライブラリで最も目立つ厄介な例の1つであるため、 Map/Setの非互換性と呼ぶこともできます。MapがCollectionとは異なるreturntypeを持つremove(Object)メソッドを定義しているという理由だけで、同じクラスにMapとSetまたはCollectionを実装させることは不可能です。

public interface Collection<E> extends Iterable<E> {
    boolean remove(Object o);
}
public interface Set<E> extends Collection<E> {
}
public interface Map<K,V> {
    V remove(Object key);
}
于 2010-02-14T18:26:46.713 に答える
1

この名前を見たことがあるかどうかは覚えていません。Java言語仕様では、これにも名前はありません。

于 2010-02-14T17:31:20.543 に答える
1

インターフェイスは、実装ではなく、インターフェイス(実装クラスが定義する必要のある一連のメソッド)を適切に記述しているだけなので、これを多重継承の問題と呼ぶことを躊躇します。インターフェイスを他のインターフェイスで拡張することは、サブインターフェイスがスーパーインターフェイスから継承することを実際に意味するのではなく、サブインターフェイスが本質的に2つで定義されたメソッドの連結であることを意味します。

3番目のインターフェイスを使用してサブインターフェイスを拡張し、競合するメソッド宣言を提供する場合、同じインターフェイスで同じ2つの競合するメソッドを提供した場合と基本的に同じです。

于 2010-02-14T17:25:26.470 に答える
0

あなたが説明する問題は、Javaだけでなく.NETにも存在しますが、そこには簡単な解決策があります。.NETFrameworkを使用すると、クラスは別の名前のクラスメンバーを使用してインターフェイスメンバーを実装できます。したがって、戻り型のみが異なる2つのインターフェイスメンバーを実装するクラスメソッドは、異なる名前を持つ必要がありますが、同じ名前のインターフェイスメンバーを実装する機能を妨げるものではありません。

インターフェイスが競合するメンバーを持つ2つのインターフェイスを継承する場合、複合インターフェイスを実装するクラスは、競合するインターフェイスを直接継承したかのようにメンバーを実装できます。結合されたインターフェイスの利用者は、通常、参照を他のインターフェイスタイプのいずれかに変換せずに、いずれかのコンポーネントインターフェイスのメンバーを使用することはできませんが、問題のキャストはダウンキャストではなくアップキャストと見なされます。

.NETに実装されているスキームはそこでうまく機能します。残念ながら、Javaで同様のことを行う方法はありません。インターフェイスが競合するメンバーを持つ他のインターフェイスを継承した場合にJavaが機能するかどうかはわかりませんが、その時点で機能するかどうかに関係なく、Javaを実装できるクラスを作成する方法はありません。

于 2013-12-18T00:11:51.507 に答える
-2

Javaのインターフェースはメソッドを実装できないため、名前が定義されていないと思います。したがって、特定のメソッドへの実装は常に1つしかないため、あいまいさが発生しないため、問題は回避されます。

私は要点を見逃しましたか、それとも「c」変数について話しているのですか?

于 2010-02-14T17:23:03.017 に答える