9

インターフェイス A とインターフェイス B の 2 つのインターフェイスがあるとします。

public interface A {
  public int data();
}

public interface B {
  public char data();
}

インターフェイス A にはメソッドがpublic int data()あり、インターフェイス B にはメソッドがありますpublic char data()

クラス C にインターフェイス A と B の両方を実装すると、コンパイラでエラーが発生します。これはJavaの欠陥ですか?これが、複数のクラスを拡張することが許可されていない主な理由の 1 つであると思いますが、この問題がまだ続くのに、なぜ複数のインターフェイスを実装することが許可されているのでしょうか?

4

4 に答える 4

7

Java チュートリアル: メソッドの定義 - メソッドのオーバーロードには、

Java プログラミング言語はメソッドのオーバーロードをサポートしており、Java は異なるメソッド シグネチャを持つメソッドを区別できます。これは、クラス内のメソッドが異なるパラメーター リストを持つ場合、同じ名前を持つことができることを意味します。

また、

コンパイラはそれらを区別できないため、同じ名前、同じ数と型の引数を持つ複数のメソッドを宣言することはできません。

コンパイラは、メソッドを区別するときに戻り値の型を考慮しないため、戻り値の型が異なっていても、同じシグネチャで 2 つのメソッドを宣言することはできません。

実装された 2 つのメソッドは共通のメソッド シグネチャ(つまりdata()) を共有するため、コンパイラは 2 つを区別できず、その 1 つのメソッドで両方のインターフェイス コントラクトを満たします。


編集:

例えば、

public class Foo implements IFoo, IBar{

    public static void main(String[] args) {
        Foo foo = new Foo();
        ((IFoo) foo).print();
        ((IBar) foo).print();
    }

    @Override
    public void print() {
        System.out.println("Hello, World!");
    }
}

public interface IBar {
    void print();
}

public interface IFoo {
    void print();
}

出力するもの、

Hello, World! 
Hello, World!
于 2012-06-23T19:07:46.923 に答える
4

Javaコンパイラ(C#もそうだと思います)は、戻り値によってメソッドを区別しません。あなたの場合、リターンタイプの違いにもかかわらず、コンパイラは両方のメソッドを同じと見なします

于 2012-06-23T19:44:48.047 に答える
2

あなたが提示した問題は、多重継承とは関係ありません。また、複数のインターフェイスを実装するクラスの実装でもありません。

インターフェイスを定義するとき、このインターフェイスの実装者は契約に同意し、そのインターフェイスで定義されたすべてのメソッドを実装する必要があると言っているだけです。

クラスの実装は問題なく複数のインターフェイスを実装できますが、インターフェイスが競合することはありません。あなたの場合同じ signature でメソッドを宣言する 2 つのインターフェイスを実装しようとしています。

メソッド シグネチャは、Java では名前とパラメータの型で構成されます。

定義: メソッド宣言の 2 つのコンポーネントは、メソッドのシグネチャ (メソッドの名前とパラメーターの型) を構成します。

http://docs.oracle.com/javase/tutorial/java/javaOO/methods.html

メソッドをオーバーロードするには、異なるシグネチャが必要です。

メソッドが複数のスーパークラスによって実装されている場合、どの実装を行うべきかを定義するなどの複雑な問題があるため、Java の多重継承は許可されていません。このトピックについては、ダイヤモンド問題を調べることをお勧めします

実際、インターフェイスは複数の継承をシミュレートするためにいくつかの状況で使用され、クラスがメソッドのマージされたセットを提示できるようにします。

于 2012-06-23T19:08:22.963 に答える
0

1つの解決策は、内部クラスを使用することです。

  1. 「クラスC」はインターフェース「A」を実装します

  2. インターフェイス「C」を実装する内部クラス「D」もあります。

    パブリッククラスCはAを実装します{...プライベートクラスDはBを実装します{

同じクラスで両方のインターフェースが本当に必要な場合は、これでケーキを手に入れて食べることもできます:)

于 2012-06-23T19:13:31.707 に答える