このコードは完全に機能します。 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();
それはインターフェースなので、害はありません。基本的に、C
とA
を実装することにより、B
クラスの青写真を使用しています。 A
とB
はどちらも、C
はtest()
というメソッドを実装する必要があると言っています。
C
クラスはそのメソッドを実装しているので、インターフェースはその役割を果たしています。
基本的にはあなたのC
クラスが次のように言っています:「ああ、インターフェースA
のためにtest()
を実装する必要があります」そしてあなたはそれを実装します。次に、C
クラスに「インターフェースB
のため、test()
を再度実装する必要があります」と表示されます。test()
実装されているので満足しています。
詳細については、こちらをご覧ください: JLS§8.4.8.4
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
インターフェースを設計することを知る方法がなかったからです。メソッド署名。
インターフェイスを作成する人にとっては、名前の衝突がまれになるようにメソッド名を十分に一意にすることをお勧めします。
JLS§8.4.8.4 は言う、
オーバーライドと同等のシグネチャを使用してメソッドを継承する
クラスは、オーバーライドと同等のシグネチャを持つ複数のメソッドを継承することができます(§8.4.2)
…
同じメソッド宣言がインターフェースから継承される可能性のあるパスがいくつかある場合があります。この事実は問題を引き起こさず、それ自体でコンパイル時エラーが発生することはありません。
クラスに同じ名前と署名を持つ複数の宣言がある場合、クラスは複数のパスを介してそれらを継承している可能性があるため(たとえば、インターフェイスを実装し、そのインターフェイスを実装するクラスをサブクラス化するなど)、害はないというのが理論的根拠のようです。 。
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();
}
}
構文に関する限りではありませんが、intent
の1つのmethods
が順守されていない場合、そのコントラクトは破られ、コードを考慮することができます。壊れたように。
あなたの例えを使用すると、マイケルに赤いシャツの代わりに青いシャツを着ることを約束し、2枚のシャツを着ることができない場合、少なくとも1つの約束を破る必要があります。
同じことがメソッドにも当てはまります。一方の契約を維持することがもう一方の契約を破ることを意味する場合、実際には両方のimplement
をinterfaces
するのは悪い考えです。
編集:契約が壊れています、Class C signature
2つのメソッドを実装する必要がありますが、最終的には1つのmethod
のみを実装し、別のメソッドを省略します。