Warum gibt es in Java keine Mehrfachvererbung, aber die Implementierung mehrerer Schnittstellen ist zulässig?


153

Java erlaubt keine Mehrfachvererbung, aber die Implementierung mehrerer Schnittstellen. Warum?


1
Ich habe den Fragentitel bearbeitet, um ihn aussagekräftiger zu gestalten.
Bozho

4
Interessanterweise wird es im JDK 8 Erweiterungsmethoden geben, mit denen die Implementierung von Schnittstellenmethoden definiert werden kann. Regeln wurden Mehrfachvererbung von Verhalten zu regeln definiert, aber nicht des Staates (was ich verstehen , mehr ist problematisch .
Edwin Dalorzo

1
Bevor ihr Zeit mit Antworten verschwendet, die euch nur sagen "Wie Java Mehrfachvererbung erreicht" ... Ich schlage vor, dass ihr zur Antwort von @Prabal Srivastava geht, die euch logischerweise sagt, was intern passieren muss, damit Klassen dieses Recht nicht zulassen. . und erlauben nur Schnittstellen das Recht, Mehrfachvererbung zuzulassen.
Yo Apps

Antworten:


228

Da Schnittstellen nur angeben, was die Klasse tut, nicht wie sie es tut.

Das Problem bei der Mehrfachvererbung besteht darin, dass zwei Klassen unterschiedliche Methoden definieren können, um dasselbe zu tun, und die Unterklasse nicht auswählen kann, welche ausgewählt werden soll.


8
Ich habe C ++ gemacht und bin einige Male auf genau dasselbe Problem gestoßen. Ich habe kürzlich gelesen, dass Scala "Eigenschaften" hat, die mir wie etwas zwischen der "C ++" - und der "Java" -Methode erscheinen.
Niels Basjes

2
Auf diese Weise vermeiden Sie das "Diamantproblem": en.wikipedia.org/wiki/Diamond_problem#The_diamond_problem
Nick L.

6
Seit Java 8 können Sie zwei identische Standardmethoden definieren, eine in jeder Schnittstelle. Wenn Sie beide Schnittstellen in Ihrer Klasse implementieren, müssen Sie diese Methode in der Klasse selbst überschreiben, siehe: docs.oracle.com/javase/tutorial/java/IandI/…
Bobbel

6
Diese Antwort ist nicht korrekt. Das Problem besteht nicht darin, das Wie anzugeben, und Java 8 soll dies beweisen. In Java 8 können zwei Super-Interfaces dieselbe Methode mit unterschiedlichen Implementierungen deklarieren. Dies ist jedoch kein Problem, da die Interface-Methoden virtuell sind. Sie können sie also einfach überschreiben und das Problem ist behoben. Das eigentliche Problem besteht in der Mehrdeutigkeit der Attribute , da Sie diese Mehrdeutigkeit beim Überschreiben des Attributs nicht lösen können (Attribute sind nicht virtuell).
Alex Oliveira

1
Was meinst du mit "Attribute"?
Bozho

96

Einer meiner Hochschullehrer erklärte es mir folgendermaßen:

Angenommen, ich habe eine Klasse, die ein Toaster ist, und eine andere Klasse, die NuclearBomb ist. Sie könnten beide eine "Dunkelheit" -Einstellung haben. Beide haben eine on () -Methode. (Einer hat ein off (), der andere nicht.) Wenn ich eine Klasse erstellen möchte, die eine Unterklasse von beiden ist ... wie Sie sehen können, ist dies ein Problem, das mir hier wirklich in die Luft jagen könnte .

Eines der Hauptprobleme ist also, dass zwei übergeordnete Klassen möglicherweise unterschiedliche Implementierungen derselben Funktion haben - oder möglicherweise zwei unterschiedliche Funktionen mit demselben Namen, wie im Beispiel meines Lehrers. Dann müssen Sie entscheiden, welche Ihre Unterklasse verwenden wird. Es gibt sicherlich Möglichkeiten, damit umzugehen - C ++ tut dies -, aber die Entwickler von Java waren der Meinung, dass dies die Dinge zu kompliziert machen würde.

Mit einer Schnittstelle beschreiben Sie jedoch etwas, zu dem die Klasse in der Lage ist, anstatt die Methode einer anderen Klasse zu übernehmen, etwas zu tun. Mehrere Schnittstellen verursachen viel seltener schwierige Konflikte, die gelöst werden müssen, als mehrere übergeordnete Klassen.


5
Danke, NomeN. Die Quelle des Zitats war ein Doktorand namens Brendan Burns, der zu dieser Zeit auch das Open-Source-Quell-Repository von Quake 2 betreute. Stelle dir das vor.
Syntactic

4
Das Problem mit dieser Analogie ist, dass, wenn Sie eine Unterklasse einer Atombombe und eines Toasters erstellen, der "Nuklear-Toaster" bei Verwendung vernünftigerweise explodieren würde.
101100

19
Wenn jemand beschließt, eine Atombombe und einen Toaster zu mischen, hat er es verdient, dass die Bombe in seinem Gesicht explodiert. Das Zitat ist trügerische Argumentation
masoud

1
Dieselbe Programmiersprache erlaubt die mehrfache Vererbung von "Schnittstellen", daher gilt diese "Begründung" nicht.
Neugieriger

24

Da die Vererbung überbeansprucht wird, auch wenn Sie nicht sagen können : "Hey, diese Methode sieht nützlich aus, ich werde diese Klasse auch erweitern."

public class MyGodClass extends AppDomainObject, HttpServlet, MouseAdapter, 
             AbstractTableModel, AbstractListModel, AbstractList, AbstractMap, ...

Können Sie erklären, warum Sie sagen, dass die Vererbung überbeansprucht wird? Eine Gottklasse zu schaffen ist genau das, was ich tun möchte! Ich finde so viele Leute, die sich um die Einzelvererbung kümmern, indem sie "Tools" -Klassen mit statischen Methoden erstellen.
Duncan Calvert

9
@ DuncanCalvert: Nein, das möchten Sie nicht, nicht wenn dieser Code jemals gewartet werden muss. Viele statische Methoden verfehlen den Punkt von OO, aber eine übermäßige Mehrfachvererbung ist viel schlimmer, da Sie völlig den Überblick verlieren, welcher Code wo verwendet wird und was eine Klasse konzeptionell ist. Beide versuchen, das Problem zu lösen: "Wie kann ich diesen Code dort verwenden, wo ich ihn brauche?", Aber das ist ein einfaches kurzfristiges Problem. Das viel schwierigere langfristige Problem, das durch ein korrektes OO-Design gelöst wird, lautet: "Wie kann ich diesen Code ändern, ohne dass das Programm auf unvorhersehbare Weise an 20 verschiedenen Stellen
Michael Borgwardt

2
@DuncanCalvert: und Sie lösen das, indem Sie Klassen mit hoher Kohäsion und geringer Kopplung haben, was bedeutet, dass sie Daten und Code enthalten, die intensiv miteinander interagieren, aber nur über eine kleine, einfache öffentliche API mit dem Rest des Programms interagieren. Dann können Sie über diese API anstelle der internen Details nachdenken, was wichtig ist, da die Benutzer nur eine begrenzte Anzahl von Details gleichzeitig im Auge behalten können.
Michael Borgwardt

18

Die Antwort auf diese Frage liegt in der internen Arbeitsweise des Java-Compilers (Konstruktorverkettung). Wenn wir die interne Arbeitsweise des Java-Compilers sehen:

public class Bank {
  public void printBankBalance(){
    System.out.println("10k");
  }
}
class SBI extends Bank{
 public void printBankBalance(){
    System.out.println("20k");
  }
}

Nach dem Kompilieren sieht dies so aus:

public class Bank {
  public Bank(){
   super();
  }
  public void printBankBalance(){
    System.out.println("10k");
  }
}
class SBI extends Bank {
 SBI(){
   super();
 }
 public void printBankBalance(){
    System.out.println("20k");
  }
}

Wenn wir die Klasse erweitern und ein Objekt daraus erstellen, wird eine Konstruktorkette bis zur ObjectKlasse ausgeführt.

Der obige Code läuft einwandfrei. aber wenn wir eine andere Klasse haben, Cardie erweitert wird, Bankund eine Hybridklasse (Mehrfachvererbung), die aufgerufen wird SBICar:

class Car extends Bank {
  Car() {
    super();
  }
  public void run(){
    System.out.println("99Km/h");
  }
}
class SBICar extends Bank, Car {
  SBICar() {
    super(); //NOTE: compile time ambiguity.
  }
  public void run() {
    System.out.println("99Km/h");
  }
  public void printBankBalance(){
    System.out.println("20k");
  }
}

In diesem Fall kann (SBICar) keine Konstruktorkette erstellen ( Mehrdeutigkeit der Kompilierungszeit ).

Für Schnittstellen ist dies zulässig, da wir kein Objekt daraus erstellen können.

Für ein neues Konzept defaultund eine neue staticMethode verweisen wir bitte auf die Standardeinstellung in der Schnittstelle .

Hoffe, dies wird Ihre Frage lösen. Vielen Dank.


7

Das Implementieren mehrerer Schnittstellen ist sehr nützlich und verursacht weder Sprachimplementierern noch Programmierern große Probleme. So ist es erlaubt. Mehrfachvererbung ist zwar auch nützlich, kann den Benutzern jedoch ernsthafte Probleme bereiten (gefürchteter Diamant des Todes ). Und die meisten Dinge, die Sie mit Mehrfachvererbung tun, können auch durch Komposition oder unter Verwendung innerer Klassen erledigt werden. Mehrfachvererbung ist daher verboten, da sie mehr Probleme als Gewinne mit sich bringt.


Was ist das Problem mit dem "Diamanten des Todes"?
Neugieriger

2
@curiousguy Enthält mehr als ein Unterobjekt derselben Basisklasse, Mehrdeutigkeit (Überschreiben, von der die Basisklasse verwendet wird), komplizierte Regeln zum Auflösen dieser Mehrdeutigkeit.
Tadeusz Kopec

@curiousguy: Wenn ein Framework vorsieht, dass das Umwandeln einer Objektreferenz in eine Referenz vom Basistyp identitätserhaltend ist, muss jede Objektinstanz genau eine Implementierung einer Basisklassenmethode haben. Wenn ToyotaCarund HybridCarbeide abgeleitet von Carund überschrieben Car.Drive, und wennPriusCar beide geerbt , aber nicht überschrieben werdenDrive , hat das System keine Möglichkeit zu identifizieren, was die virtuelle Car.DrivePerson tun soll. Schnittstellen vermeiden dieses Problem, indem sie den oben kursiven Zustand vermeiden.
Supercat

1
@supercat "Das System hätte keine Möglichkeit zu identifizieren, was das virtuelle Car.Drive tun soll." <- Oder es könnte einfach einen Kompilierungsfehler geben und Sie dazu bringen, einen explizit auszuwählen, wie es C ++ tut.
Chris Middleton

1
@ChrisMiddleton: Eine Methode void UseCar(Car &foo); Es kann nicht erwartet werden, dass eine Disambiguierung zwischen ToyotaCar::Driveund enthalten ist HybridCar::Drive(da es oft weder wissen noch darauf achten sollte, dass diese anderen Typen überhaupt existieren ). Eine Sprache könnte, wie C ++, erfordern, dass der Code ToyotaCar &myCar, an den er übergeben werden soll, UseCarzuerst an entweder HybridCaroder umgewandelt wird ToyotaCar, aber seit ((Car) (HybridCar) myCar) .Drive` und((Car)(ToyotaCar)myCar).Drive verschiedene Dinge tut, was bedeuten würde, dass die Upcasts waren nicht identitätserhaltend.
Supercat

6

Eine genaue Antwort auf diese Frage finden Sie auf der Oracle-Dokumentationsseite zur Mehrfachvererbung

  1. Mehrfache Vererbung des Status: Fähigkeit, Felder von mehreren Klassen zu erben

    Ein Grund, warum die Java-Programmiersprache es Ihnen nicht erlaubt, mehr als eine Klasse zu erweitern, besteht darin, die Probleme der Mehrfachvererbung des Status zu vermeiden, dh die Fähigkeit, Felder von mehreren Klassen zu erben

    Wenn Mehrfachvererbung zulässig ist und Wenn Sie ein Objekt durch Instanziieren dieser Klasse erstellen, erbt dieses Objekt Felder von allen Oberklassen der Klasse. Es wird zwei Probleme verursachen.

    1. Was ist, wenn Methoden oder Konstruktoren aus verschiedenen Superklassen dasselbe Feld instanziieren?
    2. Welche Methode oder welcher Konstruktor hat Vorrang?
  2. Mehrfachvererbung der Implementierung: Möglichkeit, Methodendefinitionen von mehreren Klassen zu erben

    Probleme mit diesem Ansatz: Namenskonflikte und Mehrdeutigkeiten . Wenn eine Unterklasse und eine Oberklasse denselben Methodennamen (und dieselbe Signatur) enthalten, kann der Compiler nicht bestimmen, welche Version aufgerufen werden soll.

    Java unterstützt diese Art der Mehrfachvererbung jedoch mit Standardmethoden , die seit der Veröffentlichung von Java 8 eingeführt wurden. Der Java-Compiler bietet einige Regeln, um zu bestimmen, welche Standardmethode eine bestimmte Klasse verwendet.

    Weitere Informationen zur Lösung des Diamantproblems finden Sie im folgenden SE-Beitrag:

    Was sind die Unterschiede zwischen abstrakten Klassen und Schnittstellen in Java 8?

  3. Mehrfachvererbung des Typs: Fähigkeit einer Klasse, mehr als eine Schnittstelle zu implementieren.

    Da die Schnittstelle keine veränderlichen Felder enthält, müssen Sie sich hier keine Gedanken über Probleme machen, die sich aus der Mehrfachvererbung des Status ergeben.



4

Java unterstützt die Mehrfachvererbung nur über Schnittstellen. Eine Klasse kann eine beliebige Anzahl von Schnittstellen implementieren, jedoch nur eine Klasse erweitern.

Mehrfachvererbung wird nicht unterstützt, da dies zu einem tödlichen Diamantproblem führt. Es kann jedoch gelöst werden, führt jedoch zu einem komplexen System, sodass die Java-Gründer die Mehrfachvererbung verworfen haben.

In einem Whitepaper mit dem Titel "Java: ein Überblick" von James Gosling im Februar 1995 ( Link ) wird eine Vorstellung davon gegeben, warum Mehrfachvererbung in Java nicht unterstützt wird.

Laut Gosling:

"JAVA lässt viele selten verwendete, schlecht verstandene und verwirrende Funktionen von C ++ aus, die unserer Erfahrung nach mehr Kummer als Nutzen bringen. Dies besteht hauptsächlich aus einer Überladung des Bedieners (obwohl es eine Überladung der Methode gibt), einer Mehrfachvererbung und umfangreichen automatischen Zwängen."


Der Link ist nicht zugänglich. Bitte überprüfen und aktualisieren Sie es.
MashukKhan

3

Aus dem gleichen Grund erlaubt C # keine Mehrfachvererbung, aber Sie können mehrere Schnittstellen implementieren.

Die Lehre aus C ++ mit Mehrfachvererbung war, dass es zu mehr Problemen führte, als es wert war.

Eine Schnittstelle ist ein Vertrag über Dinge, die Ihre Klasse implementieren muss. Sie erhalten keine Funktionalität von der Schnittstelle. Durch Vererbung können Sie die Funktionalität einer übergeordneten Klasse erben (und bei Mehrfachvererbung kann dies äußerst verwirrend sein).

Wenn Sie mehrere Schnittstellen zulassen, können Sie Entwurfsmuster (wie den Adapter) verwenden, um dieselben Arten von Problemen zu lösen, die Sie mit Mehrfachvererbung lösen können, jedoch auf eine viel zuverlässigere und vorhersehbarere Weise.


10
C # hat keine Mehrfachvererbung, gerade weil Java dies nicht zulässt. Es wurde viel später als Java entwickelt. Das Hauptproblem bei der Mehrfachvererbung war meiner Meinung nach die Art und Weise, wie den Menschen beigebracht wurde, sie links und rechts zu verwenden. Das Konzept, dass Delegation in den meisten Fällen eine viel bessere Alternative ist, gab es Anfang und Mitte der neunziger Jahre einfach nicht. Daher erinnere ich mich an Beispiele in Lehrbüchern, in denen Auto ein Rad und eine Tür und eine Windschutzscheibe ist, während Auto Räder, Türen und Windschutzscheibe enthält. Die einzige Vererbung in Java war also eine ruckartige Reaktion auf diese Realität.
Alexander Pogrebnyak

2
@AlexanderPogrebnyak: Wählen Sie zwei der folgenden drei aus: (1) Erlauben Sie identitätserhaltende Casts von einer Subtypreferenz zu einer Supertypreferenz; (2) Erlauben Sie einer Klasse, virtuelle öffentliche Mitglieder hinzuzufügen, ohne abgeleitete Klassen neu zu kompilieren. (3) Ermöglichen Sie einer Klasse, virtuelle Mitglieder implizit von mehreren Basisklassen zu erben, ohne sie explizit angeben zu müssen. Ich glaube nicht, dass es einer Sprache möglich ist, alle drei oben genannten Punkte zu verwalten. Java entschied sich für # 1 und # 2 und C # folgte diesem Beispiel. Ich glaube, dass C ++ nur # 3 übernimmt. Persönlich denke ich, dass # 1 und # 2 nützlicher sind als # 3, aber andere können sich unterscheiden.
Supercat

@supercat "Ich glaube nicht, dass eine Sprache alle drei oben genannten Funktionen verwalten kann" - wenn die Offsets der Datenelemente zur Laufzeit und nicht zur Kompilierungszeit ermittelt werden (wie in Objective-Cs "nicht fragilem ABI" ") und / oder eine Klassenbasis (dh jede konkrete Klasse hat eine eigene Mitglieder-Offset-Tabelle), dann denke ich, dass alle 3 Ziele erreicht werden können.
Das paramagnetische Croissant

@TheParamagneticCroissant: Das größte semantische Problem ist # 1. Wenn D1und D2beide vererben B, und jeder überschreibt eine Funktion f, und wenn objeine Instanz eines Typs ist , Sdie erbt von beiden D1und D2doch überschreibt nicht f, dann einen Verweis Gießen Szu D1sollte etwas , dessen Ausbeute fAnwendungen die D1Überschreibung und dem Gießen Bsollte nicht ändere das. Ebenso Gießen einen Verweis Sauf D2sollte etwas , dessen Ausbeute fAnwendungen die D2Überschreibung und Gießen Bsollte daran nichts ändern. Wenn eine Sprache das
Hinzufügen

1
@TheParamagneticCroissant: Es könnte sein, und meine Auswahlliste wurde etwas vereinfacht, um in einen Kommentar zu passen, aber die Verschiebung der Laufzeit macht es dem Autor von D1, D2 oder S unmöglich zu wissen, welche Änderungen sie vornehmen können, ohne zu brechen Verbraucher ihrer Klasse.
Supercat

2

Da dieses Thema nicht eng ist, werde ich diese Antwort veröffentlichen. Ich hoffe, dies hilft jemandem zu verstehen, warum Java keine Mehrfachvererbung zulässt.

Betrachten Sie die folgende Klasse:

public class Abc{

    public void doSomething(){

    }

}

In diesem Fall erweitert die Klasse Abc nichts richtig? Diese implizite Klasse ist nicht so schnell und erweitert die Klasse Object, die Basisklasse, mit der alles in Java funktioniert. Alles ist ein Objekt.

Wenn Sie versuchen , die Klasse zu verwenden oben sehen Sie , dass Ihre IDE können Sie Methoden verwenden , wie: equals(Object o), toString(), etc, aber du hast nicht die Methoden erklären, kamen sie von der BasisklasseObject

Du könntest es versuchen:

public class Abc extends String{

    public void doSomething(){

    }

}

Dies ist in Ordnung, da Ihre Klasse nicht implizit erweitert wird, Objectsondern erweitert wird, Stringweil Sie es gesagt haben. Betrachten Sie die folgende Änderung:

public class Abc{

    public void doSomething(){

    }

    @Override
    public String toString(){
        return "hello";
    }

}

Jetzt gibt Ihre Klasse immer "Hallo" zurück, wenn Sie toString () aufrufen.

Stellen Sie sich nun folgende Klasse vor:

public class Flyer{

    public void makeFly(){

    }

}

public class Bird extends Abc, Flyer{

    public void doAnotherThing(){

    }

}

Wieder Klasse FlyerObjekt implizit erstreckt , die das Verfahren hat toString(), wird jede Klasse diese Methode haben , da sie alle sich Objectindirekt, also, wenn Sie rufen toString()aus Bird, die toString()Java verwenden haben würde? Von Abcoder Flyer? Dies geschieht bei jeder Klasse, die versucht, zwei oder mehr Klassen zu erweitern. Um diese Art von "Methodenkollision" zu vermeiden, haben sie die Idee der Schnittstelle erstellt . Grundsätzlich könnte man sie als abstrakte Klasse betrachten, die Object nicht indirekt erweitert . Da sie abstrakt sind, müssen sie von einer Klasse implementiert werden, die ein Objekt ist (Sie können eine Schnittstelle nicht alleine instanziieren, sie muss von einer Klasse implementiert werden), damit alles weiterhin einwandfrei funktioniert.

Um Klassen von Schnittstellen zu unterscheiden, wurde das Schlüsselwort implement nur für Schnittstellen reserviert.

Sie können jede beliebige Schnittstelle in derselben Klasse implementieren, da sie standardmäßig nichts erweitert (Sie können jedoch eine Schnittstelle erstellen, die eine andere Schnittstelle erweitert, aber auch die "Vater" -Schnittstelle würde Object nicht erweitern), also ist eine Schnittstelle Nur eine Schnittstelle, und sie leiden nicht unter " Methodensignaturspaltungen ". Wenn dies der Fall ist , gibt der Compiler eine Warnung an Sie aus und Sie müssen nur die Methodensignatur ändern, um sie zu beheben (Signatur = Methodenname + Parameter + Rückgabetyp). .

public interface Flyer{

    public void makeFly(); // <- method without implementation

}

public class Bird extends Abc implements Flyer{

    public void doAnotherThing(){

    }

    @Override
    public void makeFly(){ // <- implementation of Flyer interface

    }

    // Flyer does not have toString() method or any method from class Object, 
    // no method signature collision will happen here

}

1

Weil eine Schnittstelle nur ein Vertrag ist. Und eine Klasse ist eigentlich ein Container für Daten.


Die grundlegende Schwierigkeit bei der Mehrfachvererbung besteht in der Möglichkeit, dass eine Klasse ein Mitglied über mehrere Pfade erbt, die es unterschiedlich implementieren, ohne eine eigene übergeordnete Implementierung bereitzustellen. Die Schnittstellenvererbung vermeidet dies, da die einzigen Orte, an denen Schnittstellenmitglieder implementiert werden können, Klassen sind, deren Nachkommen auf die Einzelvererbung beschränkt sind.
Supercat

1

Zum Beispiel zwei Klassen A, B mit derselben Methode m1 (). Und Klasse C erweitert sowohl A als auch B.

 class C extends A, B // for explaining purpose.

Jetzt sucht Klasse C nach der Definition von m1. Zuerst wird in der Klasse gesucht, wenn es nicht gefunden wurde, dann wird es in der Elternklasse überprüft. Sowohl A als auch B haben die Definition. Hier tritt also Mehrdeutigkeit auf, welche Definition gewählt werden soll. JAVA UNTERSTÜTZT also NICHT MEHRFACHE ERBUNG.


Wie wäre es, wenn der Java-Compiler den Compiler gibt, wenn die gleichen Methoden oder Variablen in beiden übergeordneten Klassen definiert sind, damit wir den Code ändern können ...
Siluveru Kiran Kumar

1

Java unterstützt aus zwei Gründen keine Mehrfachvererbung:

  1. In Java ist jede Klasse ein Kind der ObjectKlasse. Wenn es von mehr als einer Superklasse erbt, erhält die Unterklasse die Mehrdeutigkeit, die Eigenschaft der Objektklasse zu erwerben.
  2. In Java hat jede Klasse einen Konstruktor, ob wir ihn explizit oder gar nicht schreiben. Die erste Anweisung ruft super()auf, um den Konstruktor der Supper-Klasse aufzurufen. Wenn die Klasse mehr als eine Superklasse hat, wird sie verwirrt.

Wenn sich eine Klasse von mehr als einer Superklasse erstreckt, erhalten wir einen Fehler bei der Kompilierung.


0

Nehmen wir zum Beispiel den Fall, dass Klasse A eine getSomething-Methode und Klasse B eine getSomething-Methode hat und Klasse C A und B erweitert. Was würde passieren, wenn jemand C.getSomething nennt? Es gibt keine Möglichkeit zu bestimmen, welche Methode aufgerufen werden soll.

Schnittstellen geben im Grunde nur an, welche Methoden eine implementierende Klasse enthalten muss. Eine Klasse, die mehrere Schnittstellen implementiert, bedeutet lediglich, dass die Klasse die Methoden aller dieser Schnittstellen implementieren muss. Whci würde zu keinen Problemen führen, wie oben beschrieben.


2
" Was würde passieren, wenn jemand C.getSomething anruft? " Es ist ein Fehler in C ++. Problem gelöst.
Neugieriger

Das war der Punkt ... das war ein Gegenbeispiel, das ich für klar hielt. Ich habe darauf hingewiesen, dass es keine Möglichkeit gibt zu bestimmen, welche Methode zum Abrufen von etwas aufgerufen werden soll. Auch als Randnotiz war die Frage im Zusammenhang mit Java nicht C ++
John Kane

Es tut mir leid, dass ich nicht verstehe, worum es Ihnen geht. Offensichtlich gibt es in einigen Fällen Unklarheiten mit MI. Wie ist das ein Gegenbeispiel? Wer hat behauptet, dass MI niemals zu Mehrdeutigkeiten führt? " Auch als Randnotiz bezog sich die Frage auf Java, nicht auf C ++ " Also?
Neugieriger

Ich habe nur versucht zu zeigen, warum diese Mehrdeutigkeit besteht und warum sie nicht mit Schnittstellen zusammenhängt.
John Kane

Ja, MI kann zu mehrdeutigen Anrufen führen. So kann Überlastung. Also sollte Java Überladung entfernen?
Neugieriger

0

Stellen Sie sich ein Szenario vor, in dem Test1, Test2 und Test3 drei Klassen sind. Die Klasse Test3 erbt die Klassen Test2 und Test1. Wenn die Klassen Test1 und Test2 dieselbe Methode haben und Sie sie vom untergeordneten Klassenobjekt aufrufen, besteht eine Mehrdeutigkeit beim Aufrufen der Methode der Klasse Test1 oder Test2, es gibt jedoch keine solche Mehrdeutigkeit für die Schnittstelle, da in der Schnittstelle keine Implementierung vorhanden ist.


0

Java unterstützt aufgrund von Mehrdeutigkeitsproblemen keine Mehrfachvererbung, Mehrweg- und Hybridvererbung:

 Scenario for multiple inheritance: Let us take class A , class B , class C. class A has alphabet(); method , class B has also alphabet(); method. Now class C extends A, B and we are creating object to the subclass i.e., class C , so  C ob = new C(); Then if you want call those methods ob.alphabet(); which class method takes ? is class A method or class B method ?  So in the JVM level ambiguity problem occurred. Thus Java does not support multiple inheritance.

Mehrfachvererbung

Referenzlink: https://plus.google.com/u/0/communities/102217496457095083679


0

Auf einfache Weise, die wir alle kennen, können wir eine Klasse erben (erweitern), aber wir können so viele Schnittstellen implementieren. Das liegt daran, dass wir in Schnittstellen keine Implementierung geben, sondern nur die Funktionalität. nehmen an, wenn Java kann so viele Klassen erweitert und die haben gleiche Methoden .. in diesem Punkt , wenn wir Superklasse aufzurufen Methode in der Unterklasse , welche Methode annehmen laufen versuchen ??, Compiler verwirren lassen Beispiel: - Versuchen Sie, um mehr erstreckt aber in Schnittstellen Diese Methoden haben keine Körper, die wir in der Unterklasse implementieren sollten. Versuchen Sie, mehrere Implementierungen durchzuführen, damit Sie sich keine Sorgen machen müssen.


1
Sie können diese Beispiele einfach hier posten. Ohne das sieht es aus wie ein Textblock auf eine 9 Jahre alte Frage, die hundertmal beantwortet wurde.
Pochmurnik

-1

* Dies ist eine einfache Antwort, da ich ein Anfänger in Java bin *

Bedenken Sie, dass es drei Klassen gibt X, Yund Z.

Wir erben also wie X extends Y, Z Und beide Yund Zhaben eine Methode alphabet()mit demselben Rückgabetyp und denselben Argumenten. Diese Methode alphabet()in Ysagt, dass das erste Alphabet angezeigt werden soll, und das Methodenalphabet in Zsagt, dass das letzte Alphabet angezeigt werden soll . Hier kommt also Mehrdeutigkeit, wenn von alphabet()aufgerufen wird X. Ob es heißt, erstes oder letztes Alphabet anzuzeigen ??? Java unterstützt also keine Mehrfachvererbung. Bei Schnittstellen betrachten Yund Zals Schnittstellen. Beide enthalten also die Deklaration der Methode, alphabet()aber nicht die Definition. Es wird nicht angegeben, ob das erste oder das letzte Alphabet oder etwas anderes angezeigt werden soll, sondern nur eine Methode deklariertalphabet(). Es gibt also keinen Grund, die Mehrdeutigkeit zu erhöhen. Wir können die Methode mit allem definieren, was wir innerhalb der Klasse wollen X.

Kurz gesagt, in Interfaces erfolgt die Definition nach der Implementierung, also keine Verwirrung.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.