4

Javaで多重継承が許可されていない理由についてオンラインで読んでいたので、それを説明するために次の例を示しました。

class A { 
   public void doSomething() { 
   } 
} 

class B { 
     public void doSomething() { 
     } 
} 

class C extends A,B { 

} 

public static void main(String args) { 
     C c = new C(); 
     c.doSoemthing();   // compiler doesnt know which doSeomthing to call.

上記の例は、両方の親クラスが同じメソッド名を持つダイヤモンド問題と呼ばれるものを示しています。子クラスがそれを取得しようとすると、コンパイラは混乱します。

私の質問は、インターフェイスがこの種の問題をどのように解決するかということです。

4

7 に答える 7

2

次のコードについて考えてみましょう

interface P { 
   public void doSomething();
} 

interface Q { 
     public void doSomething();
} 
class A { 
   public void doSomething() { 
   } 
} 

class B { 
     public void doSomething() { 
     } 
} 

class C implements P,Q { 
     public void doSomething(){
         // implementation
     }
}

class D extends A,B {   // suppose it is possible


}

Cのオブジェクトを使用するにはdoSomething()、Cクラスで実装しています。これはCクラスでのみ実装されています。

doSomethingしかし、D のオブジェクトを作成して、どのメソッドを呼び出せばよいでしょうか? このメソッドは A と B の両方で実装されているためです。

ダイヤモンド問題

実際、本当のダイアモンの問題は

class A { 
   public void doSomething() { 
   } 
} 

class B extends A{ 
     public void doSomething() { 
     } 
} 

class C extends A{ 
     public void doSomething() { 
     } 
} 


class D extends B,C {   // suppose it is possible
   // no implementation of doSomething.
}

ここに画像の説明を入力

ダイヤモンドの形をしていることからダイヤモンドと呼ばれています。以下を行いたい場合はこちら

D d = new D();
d.doSomething(); // which method should be called now????

ウィキペディアからここに素晴らしいリアルタイムの例があります

たとえば、GUI ソフトウェア開発のコンテキストでは、クラス Button はクラス Rectangle (外観用) と Clickable (機能/入力処理用) の両方から継承し、クラス Rectangle と Clickable は両方とも Object クラスから継承します。Button オブジェクトに対して equals メソッドが呼び出され、Button クラスにはそのようなメソッドがなく、Rectangle と Clickable の両方にオーバーライドされた equals メソッドがある場合、最終的にどのメソッドを呼び出す必要がありますか?

于 2013-05-29T15:39:07.130 に答える
2

Java のインターフェースを介して多重継承が達成されたと言うのは公平ではありません

Java のみがサポートされmultiple interface inheritance、Java はサポートされませんmultiple inheritance

In mixin inheritanceが表示されるはずです。1 つのクラスは、複数の継承スキームでクラスの 1 つとして使用されるように特別に設計されています。

http://csis.pace.edu/~bergin/patterns/multipleinheritance.html

于 2013-05-29T15:30:40.973 に答える
1

インターフェイスはメソッドを実装していないためdoSomething()、インターフェイス メソッドを呼び出すことはできません。インターフェイスは、実際の (実装する) クラスで実装するメソッドの単なる署名です。doSomething()クラスCにを実装し、それがB.doSomething()orを呼び出すときに呼び出すメソッドになりますA.doSomething()

2 つのクラスを 2 つのdoSomething()メソッドで拡張する場合、実装が異なる可能性があり、どちらが呼び出されたのかわかりません。次の例を参照してください。

class A { 
   public void doSomething() { 
       System.out.println("A");
   } 
} 

class B { 
   public void doSomething() { 
       System.out.println("B");
   } 
} 

class C extends A & B { //if this would be an option

} 

public static void main(String args) { 
    C c = new C(); 
    c.doSoemthing();   //Print "A" or "B" ???
}

結論:それは実装の問題です。インターフェイスはどのメソッドにも実装を提供しないため、同じメソッド シグネチャを持つインターフェイスから継承しても安全です。

于 2013-05-29T15:30:31.293 に答える
0

答えはあなたの質問そのものにあります。インターフェイスに実装がないため、インターフェイスコンパイラが混乱することはありません。実際の実装を提供する具体的なクラスです。したがって、混乱はありません。

于 2013-05-29T15:30:33.200 に答える