web-dev-qa-db-ja.com

Javaインターフェイスでの多重継承

Javaでは多重継承は常に違法だと思っていましたが、このコードはコンパイルします:

public interface A {
  void a();
}

public interface B {
  void b();
}

public interface AB extends A, B {
}

ABなどの空のインターフェースを持つことは悪い習慣と見なされますか?空のインターフェイスを回避しながら(ジェネリックまたはその他を使用して)同様のことを実現する方法はありますか?

注:インターフェースを介して複数の継承をシミュレートする方法は問いません。私は次のことができることを理解しています:

public class AbImpl implements A, B {
  public void a() {}
  public void b() {}
}

さまざまな理由から、両方のメソッドを持つインターフェースが必要です。

28
Jacob Wallace

implementationsの多重継承は許可されていません。ただし、コンポーネントは複数のインターフェイスを継承できます。

実装する新しいメソッドシグネチャを単に定義しているだけなので、複数のインターフェイスを継承しても問題はありません。機能の複数のコピーの継承が、従来、問題を引き起こしている、または少なくとも混乱を引き起こしていると見なされてきました(例: 死のダイヤモンド )。

28
Brian Agnew

インターフェイスは、1つ以上の他のインターフェイスを拡張できます。クラスに複数のインターフェイスを実装することもできます。インターフェイスは契約にすぎないため、合法です-実装はありません。クラスができることについては何も言わずに、クラスができることのコントラクトを定義しているだけです。

8
Maciej Ziarko

インターフェイスの実装は「継承」ではありません。これはextendクラスの場合です。

インターフェイスの実装は、クラスが何かのように見えることを宣言するために使用され、クラスを拡張することは、クラスが何かであると宣言するために使用されます。

複数の物のように「見える」ことは問題ありませんが、複数の物に「なる」ことはできません。


複数のインターフェースを拡張する空のインターフェースを使用して、一連のインターフェースを単一のインターフェースに収集し、より広いが再利用されたAPIを伝達することには何の問題もありません。

4
Bohemian

この関連する質問 で、ジェイはこれに対する答えを提供します。違いは、実装とインターフェースの指定です。

実装の問題は、2つの関数の名前が同じ場合にのみ発生します。これは、複数の実装で「f()をどのように使用しますか?」という質問に明確な選択肢がないためです。

同じ関数名の2つのインターフェイスでは、この選択を行う必要がないため、問題は発生しません。むしろ、手元にある独自のバージョンの関数を実装する必要があります。

例として、 多重継承を許可する-C++ の対応物を見ることができます。このリンクは物事をうまく説明し、いくつかのコード/画像の例を提供します。注目すべきことの1つは、とにかく関数が属するクラスを明示的にスコープする必要があるため、C++の問題を簡単に軽減できることです。

Java、ただし、実際にこれを行う必要はありません(オブジェクトにアタッチされているメソッドがある場合のみ)ので、結果として、呼び出しをスコープするメソッドはありません親クラスを参照する必要がある唯一のオプションは、superキーワードを使用するか、static関数を使用することです。そのため、これを解決する明確なオプションはありません。 Javaでは、ほとんど変更せずに、システムへの追加の変更を禁止します。

0
pseudoramble