web-dev-qa-db-ja.com

同じメソッドを持つ複数のインターフェースを実装する

このコードは完全に機能します。 test()メソッドは両方のインターフェースで機能します。ボンネットの下で正確に何が起こっているのですか?そして、この機能は実際のシナリオでどのように役立ちますか?

interface A
{
    void test();
}

interface B 
{
    void test();
}

class C implements A, B
{

    public void test() 
    {
        System.out.println("abc");
    }
}

   A a = new C();
   a.test();
   B b = new C();
   b.test();
15
Sid

それはインターフェースなので、害はありません。基本的に、CAを実装することにより、Bクラスの青写真を使用しています。 ABはどちらも、Ctest()というメソッドを実装する必要があると言っています。

Cクラスはそのメソッドを実装しているので、インターフェースはその役割を果たしています。

基本的にはあなたのCクラスが次のように言っています:「ああ、インターフェースAのためにtest()を実装する必要があります」そしてあなたはそれを実装します。次に、Cクラスに「インターフェースBのため、test()を再度実装する必要があります」と表示されます。test()実装されているので満足しています。

詳細については、こちらをご覧ください: JLS§8.4.8.4

14
JREN

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

public interface StockBroker{
        //Give our client some investment strategies.
        public String adviseClient(Client c);
}

public interface Doctor{
  //Examine our client and give them some medical advice
        public String adviseClient(Client c);
}

そして、両方のインターフェースを実装するクラス...

public class JackOfAllTrades implements StockBroker, Doctor{
   public String adviseClient(Client c){
   }
}

1つのメソッドで両方のインターフェイスを実装することは構文的に正しい場合がありますが、目的の動作が得られない場合があります。たとえば、株式仲買人と医師は通常、それぞれクライアントに大きく異なるアドバイスを提供します。

インターフェイスDoctorを実装するオブジェクトを使用している人は、adviseClient()メソッドが医学的アドバイスを提供することを期待しています。しかし、インターフェースStockBrokerを実装するオブジェクトを使用している人は、adviseClient()メソッドが投資戦略を提供することを期待しています。

この場合、オブジェクトJackOfAllTradesは、adviseClient()メソッドに、adviseClient()がと呼ばれる。

これはJavaの欠点です。なぜなら、Doctorインターフェースを設計する人は、他の誰かが同じStockBrokerインターフェースを設計することを知る方法がなかったからです。メソッド署名。

インターフェイスを作成する人にとっては、名前の衝突がまれになるようにメソッド名を十分に一意にすることをお勧めします。

6
user4574

JLS§8.4.8.4 は言う、

オーバーライドと同等のシグネチャを使用してメソッドを継承する

クラスは、オーバーライドと同等のシグネチャを持つ複数のメソッドを継承することができます(§8.4.2)

同じメソッド宣言がインターフェースから継承される可能性のあるパスがいくつかある場合があります。この事実は問題を引き起こさず、それ自体でコンパイル時エラーが発生することはありません。

クラスに同じ名前と署名を持つ複数の宣言がある場合、クラスは複数のパスを介してそれらを継承している可能性があるため(たとえば、インターフェイスを実装し、そのインターフェイスを実装するクラスをサブクラス化するなど)、害はないというのが理論的根拠のようです。 。

6
andrewdotn
interface A
{
void test();
}

interface B 
{
void test();
}
class C implements A, B {

    public void test() 
    {
        System.out.println("common to all");
    }
    public A choose(A a){
        return new A(){
           public void test() {
                System.out.println("test of A");
           }
        };
    }
    public B choose(B b){
        return new B(){
           public void test() {
            System.out.println("test of B");
           }
        };
    }
}
class Demo {
   public static void main(String[] args) {
   C c =new C();

   A a = new C();
   B b = new B();

   a = c.choose(a);
   b = c.choose(b);

   a.test();
   b.test();
   }
}
2
Pranav Tallewar

構文に関する限りではありませんが、intentの1つのmethodsが順守されていない場合、そのコントラクトは破られ、コードを考慮することができます。壊れたように

あなたの例えを使用すると、マイケルに赤いシャツの代わりに青いシャツを着ることを約束し、2枚のシャツを着ることができない場合、少なくとも1つの約束を破る必要があります。

同じことがメソッドにも当てはまります。一方の契約を維持することがもう一方の契約を破ることを意味する場合、実際には両方のimplementinterfacesするのは悪い考えです。

編集:契約が壊れています、Class C signature 2つのメソッドを実装する必要がありますが、最終的には1つのmethodのみを実装し、別のメソッドを省略します。

参照

2
Suresh Atta