2010-02-14 11 views
9

Hier ist ein Beispiel mit mehreren Schnittstellenvererbung in Java und es gibt ein Problem.Java: Wie nennt man diese Mehrfachvererbung Ambiguität?

Beachten Sie, dass ich völlig weiß, warum es ein Problem gibt, und das ist nicht der Punkt meiner Frage. Die Frage ist, wie Sie diese Multiple-Interface-Vererbungsambiguität benennen, wenn es einen Namen dafür gibt.

Zum Beispiel in C++, die Mehrdeutigkeit, die entsteht, wenn Sie mehrere Implementierungsvererbung verwenden und können nicht die überschriebene Methode bestimmen zu verwenden, wird das „Diamant-Problem“ bezeichnet:

http://en.wikipedia.org/wiki/Diamond_problem

nun wieder einmal, ich weiß, dass das hier nicht das gleiche Problem ist: darum geht es nicht. Der Punkt ist, dass in diesem vorherigen Fall ein Name geprägt wurde.

Und ich würde gerne wissen, ob ein Name für das Problem existiert, das ich beschreiben werde.

Hier ist ein Beispiel einer anderen Art von Mehrfachvererbung, wo eine Schnittstelle von zwei anderen Schnittstellen erbt, die einen inkompatible Methode Rückgabetyp haben:

interface A { 
    void a(); 
    Integer c(); 
} 

interface B { 
    void b(); 
    Long c(); 
} 

interface MI extends A, B {...} 

(Hinweis Mehrfachvererbung-Schnittstelle bei der Arbeit des ‚‘ erstreckt Verwendung Schlüsselwort)

Sie können das nicht tun, denn:

Typen A und B sind nicht kompatibel; beide definieren c(), aber mit nicht verwandten Rückkehr Typ

hat einen Namen, um diese Situation zu beschreiben geprägt worden?

+0

Was ist, wenn sie den gleichen Namen, Argumenttypen, Rückgabetypen, aber unterschiedliche inkompatible Semantik haben? Wäre dieser Fall in Ihrer Frage enthalten oder nicht? – curiousguy

Antwort

3

Ich bin mir nicht sicher, ob es einen bestimmten Namen dafür gibt, oder zumindest scheint es nicht sehr häufig verwendet zu werden. Es ist "nur" ein Problem der impliziten Abbildung von Schnittstellenmethoden auf Klassenmethoden; Wenn Sie Überladungen haben könnten, die sich nur in den Rückgabetypen unterscheiden, wäre dies ebenfalls kein Problem. Es kommt also auf ein Signatur/Overloading/implizites Methoden-Mapping-Problem an.

Im Online-Buch "Thinking in Java" gibt es auch keinen Namen dafür. http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ310_001.htm

Nur eine Randnotiz, C# ermöglicht explizite Schnittstellenimplementierungen, die dieses Problem beheben.

+0

Wird die Frage nicht genauso gestellt wie die Situation für I4 im Abschnitt "Namenskollisionen beim Kombinieren von Schnittstellen" von Ihrem Link? Also ich denke, es heißt "Namenskollisionen beim Kombinieren von Schnittstellen". Missverstehe ich? – MatrixFrog

+2

@MatrixFrog: Ja, aber "Namen Kollisionen bei der Kombination von Schnittstellen" klingt eher nach einer Beschreibung des Problems für mich, und nicht wie ein "Standard" Name für das Problem. – Lucero

-2

Ich glaube nicht, dass ein Name definiert wurde, da Interfaces in Java keine Methodenimplementierung haben können, das Problem wird daher vermieden, da es immer nur eine Implementierung zu einer bestimmten Methode gibt und somit keine Mehrdeutigkeit entsteht.

Habe ich den Punkt verpasst oder redest du von der Variable 'c'?

+0

Ja. Du hast den Punkt verpasst. Lesen Sie die Frage erneut. – shoosh

+0

... und 'c' ist keine Variable, nicht einmal ein Feld ... es ist eine Methode. – Lucero

+0

@zinc: "keine Zweideutigkeit"? In der Codebeispiel aus der Frage gibt es eine Mehrdeutigkeit: Was muss die Implementierung von 'MI.c()' zurückgeben? Ganzzahl oder lang? –

1

Ich würde zögern, dies ein Problem der Mehrfachvererbung zu nennen, weil Schnittstellen nur gut beschreiben, Schnittstelle - eine Reihe von Methoden, die eine implementierende Klasse definieren muss - und keine Implementierung. Das Erweitern einer Schnittstelle mit anderen Schnittstellen bedeutet nicht wirklich, dass die Subschnittstelle von der Superschnittstelle erbt, sondern dass die Subschnittstelle im Wesentlichen eine Verkettung der in den beiden definierten Methoden ist.

Wenn eine dritte Schnittstelle verwendet wird, um das Subinterface zu erweitern und eine widersprüchliche Methodendeklaration bereitstellt, ist dies im Wesentlichen dasselbe, als ob Sie gerade die gleichen zwei widersprüchlichen Methoden in derselben Schnittstelle bereitgestellt hätten.

+0

Ich stimme nicht zu: Java hat mehrere Schnittstellenvererbung und ich habe mehrmals in meiner Frage angegeben, dass es um die Vererbung mehrerer Schnittstellen ging. Und dann werden die Schlüsselwörter "extends" speziell verwendet. Dann denken einige, dass die Vererbung mehrerer Schnittstellen mehrfache Vererbung ist, weil die Implementierung schließlich nur ein Detail ist (die Implementierung existiert nicht auf der OOA/OOD-Ebene, sie ist wirklich nur ein OOP-Detail). Die Schnittstelle C erbt sicherlich die Abstraktionen, die von A und B definiert sind, und als OOD für OOP-Translationisten sind alles, was mir wichtig ist, Abstraktionen, keine Implementierungsdetails. – SyntaxT3rr0r

+0

@Tom: Dann, um Ihren zweiten Punkt zu adressieren: es ist komplizierter als einfach zu versuchen, zwei in Konflikt stehende Methoden in der gleichen Klasse oder in der Schnittstelle zur Verfügung zu stellen. Das Beispiel hier ist der einzige Fall, in dem Sie eine Schnittstelle erben (beachten Sie das Schlüsselwort 'extends') * von zwei Abstraktionen *, die nicht funktionieren wird. In allen anderen Fällen können Sie immer die Vererbung mehrerer Schnittstellen in Java verwenden. – SyntaxT3rr0r

+0

Ich stimme nicht mit einem bestimmten Punkt von Ihnen überein, und ich bin mir der Multiple-Interface-Extension-Fähigkeit von Java bewusst. Ich habe nur darauf hingewiesen, "so siehst du es an." Ich weiß, dass es Unterschiede auf einer objektorientierten Design-Ebene gibt. Wenn man jedoch genau darauf eingeht, wie (jenseits der Semantik und der Tatsache, dass eine Klasse Superinterfaces implementieren kann, ohne Subinterfaces zu implementieren), eine Schnittstelle eine andere als die Bereitstellung aller definierten Methoden in einer Schnittstelle erweitert? – Tom

2

Ich kenne auch keinen bestimmten Namen für dieses Problem. Wann immer es entstand, wurde es in einem Satz beschrieben, der die Wörter Rückgabetyp Inkompatibilität irgendwann enthält. Man könnte es auch Karte/Satz Inkompatibilität nennen, da dies eines der prominenteren und ärgerlicheren Beispiele in den Java-Klassenbibliotheken ist. Es macht es unmöglich, dieselbe Klasse sowohl Map als auch Set oder Collection zu implementieren, nur weil Map eine Methode remove (Object) mit einem anderen Rückgabetyp als Collection definiert.

public interface Collection<E> extends Iterable<E> { 
    boolean remove(Object o); 
} 
public interface Set<E> extends Collection<E> { 
} 
public interface Map<K,V> { 
    V remove(Object key); 
} 
0

Das Problem, das Sie in .NET beschreiben ist ebenso vorhanden wie Java, hat aber eine einfache Lösung gibt: das .NET Framework ermöglicht eine Klasse eine Schnittstelle Element verwendet einen Teilnehmer mit einem anderen Namen zu implementieren. Obwohl die Klassenmethoden, die zwei Schnittstellenelemente implementieren, die sich nur im Rückgabetyp unterscheiden, unterschiedliche Namen haben müssen, schließt dies nicht ihre Fähigkeit aus, Schnittstellenelemente mit demselben Namen zu implementieren.

Wenn eine Schnittstelle zwei Schnittstellen mit in Konflikt stehenden Elementen erbt, kann eine Klasse, die die zusammengesetzte Schnittstelle implementiert, die Elemente so implementieren, als ob sie die in Konflikt stehenden Schnittstellen direkt geerbt hätten. Verbraucher der kombinierten Schnittstelle können im Allgemeinen nicht die Mitglieder einer der Komponentenschnittstellen verwenden, ohne die Referenz auf einen der anderen Schnittstellentypen zu konvertieren, aber die fragliche Besetzung wird als Upcast und nicht als Downcast betrachtet.

Das in .NET implementierte Schema funktioniert gut dort. Leider gibt es in Java keine Möglichkeit, etwas Ähnliches zu tun. Ich weiß nicht, dass Java quieken wird, wenn ein Interface andere Interfaces mit in Konflikt stehenden Mitgliedern erbt, aber ob es an diesem Punkt krächzt oder nicht, es würde keine Möglichkeit geben, eine Klasse zu erzeugen, die es implementieren könnte.