Ich weiß, dass Mehrfachvererbung in Java und C # nicht zulässig ist. Viele Bücher sagen nur, Mehrfachvererbung ist nicht erlaubt. Es kann jedoch mithilfe von Schnittstellen implementiert werden. Es wird nichts darüber diskutiert, warum es nicht erlaubt ist. Kann mir jemand genau sagen, warum es nicht erlaubt ist?
c#
java
language-design
multiple-inheritance
Abdulsattar Mohammed
quelle
quelle
Antworten:
Die kurze Antwort lautet: Weil sich die Sprachdesigner dagegen entschieden haben.
Grundsätzlich schien es, dass sowohl die .NET- als auch die Java-Designer keine Mehrfachvererbung zuließen, da sie der Ansicht waren, dass das Hinzufügen von MI den Sprachen zu viel Komplexität hinzufügte und gleichzeitig zu wenig Nutzen brachte .
Für eine unterhaltsamere und ausführlichere Lektüre stehen im Internet einige Artikel mit Interviews einiger Sprachdesigner zur Verfügung. Für .NET hat beispielsweise Chris Brumme (der bei MS an der CLR gearbeitet hat) die Gründe erläutert, warum er sich entschieden hat, dies nicht zu tun:
Den vollständigen Artikel können Sie hier lesen.
Für Java können Sie lesen diesen Artikel :
quelle
Eine mehrfache Vererbung der Implementierung ist nicht zulässig.
Das Problem ist, dass der Compiler / die Laufzeit nicht herausfinden kann, was zu tun ist, wenn Sie eine Cowboy- und eine Artist-Klasse haben, beide mit Implementierungen für die draw () -Methode, und dann versuchen, einen neuen CowboyArtist-Typ zu erstellen. Was passiert, wenn Sie die draw () -Methode aufrufen? Liegt jemand tot auf der Straße oder hast du ein schönes Aquarell?
Ich glaube, es heißt das Problem der doppelten Diamantvererbung.
quelle
Grund: Java ist aufgrund seiner Einfachheit sehr beliebt und einfach zu codieren.
Was auch immer Java-Entwickler für Programmierer schwierig und kompliziert zu verstehen fühlen, sie haben versucht, dies zu vermeiden. Eine solche Art von Eigenschaft ist die Mehrfachvererbung.
Problem mit Mehrfachvererbung: Diamantproblem.
Beispiel :
Dies ist die Mehrdeutigkeit, die im Diamantproblem besteht.
Es ist nicht unmöglich, dieses Problem zu lösen, aber es schafft mehr Verwirrung und Komplexität für den Programmierer beim Lesen. Es verursacht mehr Probleme als es zu lösen versucht.
Hinweis : Auf jeden Fall können Sie die Mehrfachvererbung jederzeit indirekt über Schnittstellen implementieren.
quelle
Weil Java eine ganz andere Designphilosophie hat als C ++. (Ich werde hier nicht über C # sprechen.)
Beim Entwerfen von C ++ wollte Stroustrup nützliche Funktionen einbeziehen, unabhängig davon, wie sie missbraucht werden könnten. Es ist möglich, mit Mehrfachvererbung, Überladung von Bedienern, Vorlagen und verschiedenen anderen Funktionen große Probleme zu haben, aber es ist auch möglich, einige sehr gute Dinge damit zu tun.
Die Java-Designphilosophie besteht darin, die Sicherheit in Sprachkonstrukten zu betonen. Das Ergebnis ist, dass es Dinge gibt, die viel umständlicher zu tun sind, aber Sie können viel sicherer sein, dass der Code, den Sie betrachten, genau das bedeutet, was Sie denken, dass er tut.
Darüber hinaus war Java weitgehend eine Reaktion von C ++ und Smalltalk, den bekanntesten OO-Sprachen. Es gibt viele andere OO-Sprachen (Common Lisp war tatsächlich die erste, die standardisiert wurde), mit verschiedenen OO-Systemen, die MI besser handhaben.
Ganz zu schweigen davon, dass es durchaus möglich ist, MI in Java mithilfe von Schnittstellen, Komposition und Delegierung durchzuführen. Es ist expliziter als in C ++ und daher umständlicher zu verwenden, bietet Ihnen jedoch etwas, das Sie auf den ersten Blick eher verstehen.
Hier gibt es keine richtige Antwort. Es gibt verschiedene Antworten, und welche für eine bestimmte Situation besser ist, hängt von den Anwendungen und den individuellen Vorlieben ab.
quelle
Der Hauptgrund (obwohl keineswegs der einzige), warum Menschen sich von MI abwenden, ist das sogenannte "Diamantproblem", das zu Unklarheiten bei Ihrer Implementierung führt. Dieser Wikipedia-Artikel beschreibt es und erklärt es besser als ich. MI kann auch zu komplexerem Code führen, und viele OO-Designer behaupten, dass Sie MI nicht benötigen, und wenn Sie es verwenden, ist Ihr Modell wahrscheinlich falsch. Ich bin mir nicht sicher, ob ich diesem letzten Punkt zustimme, aber es ist immer ein guter Plan, die Dinge einfach zu halten.
quelle
In C ++ war die Mehrfachvererbung bei unsachgemäßer Verwendung ein großes Problem. Um diese beliebten Designprobleme zu vermeiden, wurde stattdessen in modernen Sprachen (Java, C #) die Vererbung mehrerer Schnittstellen erzwungen.
quelle
Mehrfachvererbung ist
Daher kann es eine kluge Wahl sein berücksichtigt nicht die Mehrfachvererbung in die Java - Sprache enthalten.
quelle
Ein weiterer Grund ist, dass die Einzelvererbung das Casting trivial macht und keine Assembler-Anweisungen ausgibt (außer bei Bedarf die Kompatibilität der Typen zu überprüfen). Wenn Sie mehrfach vererbt wurden, müssen Sie herausfinden, wo in der untergeordneten Klasse ein bestimmter Elternteil beginnt. Leistung ist also sicherlich ein Vorteil (obwohl nicht der einzige).
quelle
In den alten Tagen (70er Jahre), als Informatik mehr Wissenschaft und weniger Massenproduktion war, hatten die Programmierer Zeit, über gutes Design und gute Implementierung nachzudenken, und als Ergebnis hatten die Produkte (Programme) eine hohe Qualität (z. B. TCP / IP-Design) und Umsetzung). Heutzutage, wenn alle programmieren und die Manager die Spezifikationen vor Ablauf der Fristen ändern, sind subtile Probleme, wie sie im Wikipedia-Link von Steve Haigh beschrieben sind, schwer zu verfolgen. Daher ist die "Mehrfachvererbung" durch das Compiler-Design begrenzt. Wenn es dir gefällt, kannst du immer noch C ++ verwenden ... und hast alle Freiheiten, die du willst :)
quelle
Ich nehme die Aussage, dass "Mehrfachvererbung in Java nicht erlaubt ist" mit einer Prise Salz.
Mehrfachvererbung wird definiert, wenn ein "Typ" von mehr als einem "Typ" erbt. Und Schnittstellen werden aufgrund ihres Verhaltens auch als Typen klassifiziert. Java hat also eine Mehrfachvererbung. Nur dass es sicherer ist.
quelle
Das dynamische Laden von Klassen erschwert die Implementierung der Mehrfachvererbung.
In Java haben sie die Komplexität der Mehrfachvererbung vermieden, indem sie stattdessen eine Einzelvererbung und eine Schnittstelle verwendet haben. Die Komplexität der Mehrfachvererbung ist in einer Situation wie unten erläutert sehr hoch
Diamantproblem der Mehrfachvererbung. Wir haben zwei Klassen B und C, die von A erben. Angenommen, B und C überschreiben eine geerbte Methode und stellen ihre eigene Implementierung bereit. Jetzt erbt D sowohl von B als auch von C und führt eine Mehrfachvererbung durch. D sollte diese überschriebene Methode erben, kann jvm nicht entscheiden, welche überschriebene Methode verwendet wird?
In C ++ werden virtuelle Funktionen verwendet, um zu behandeln, und wir müssen explizit tun.
Dies kann durch die Verwendung von Schnittstellen vermieden werden, es gibt keine Methodenkörper. Schnittstellen können nicht instanziiert werden - sie können nur von Klassen implementiert oder durch andere Schnittstellen erweitert werden.
quelle
Tatsächlich entsteht eine Mehrfachvererbung in der Komplexität, wenn die geerbten Klassen dieselbe Funktion haben. dh der Compiler wird eine Verwirrung haben, die man wählen muss (Diamantproblem). In Java wurde diese Komplexität entfernt und eine Schnittstelle bereitgestellt, um die Funktionalität zu erhalten, die eine Mehrfachvererbung bietet. Wir können Schnittstelle verwenden
quelle
Java hat ein Konzept, dh Polymorphismus. Es gibt zwei Arten von Polymorphismus in Java. Es gibt Methodenüberladung und Methodenüberschreibung. Unter diesen tritt das Überschreiben von Methoden bei Beziehungen zwischen Super- und Unterklassen auf. Wenn wir ein Objekt einer Unterklasse erstellen und die Methode der Oberklasse aufrufen und wenn die Unterklasse mehr als eine Klasse erweitert, welche Oberklassenmethode sollte aufgerufen werden?
Oder wird beim Aufrufen des Superklassenkonstruktors von
super()
welcher Superklassenkonstruktor aufgerufen?Diese Entscheidungen sind aufgrund der aktuellen Java-API-Funktionen nicht möglich. Daher ist Mehrfachvererbung in Java nicht zulässig.
quelle
Mehrfachvererbung ist in Java nicht direkt zulässig, aber über Schnittstellen.
Grund :
Mehrfachvererbung: stellt mehr Komplexität und Mehrdeutigkeit.
Schnittstellen: Schnittstellen sind vollständig abstrakte Klassen in Java, mit denen Sie die Struktur oder das Innenleben Ihres Programms auf einheitliche Weise von der öffentlich verfügbaren Schnittstelle abgrenzen können. Dies führt zu mehr Flexibilität und wiederverwendbarem Code sowie zu mehr Kontrolle darüber, wie Sie andere Klassen erstellen und mit ihnen interagieren.
Genauer gesagt handelt es sich um ein spezielles Konstrukt in Java mit dem zusätzlichen Merkmal, mit dem Sie eine Art Mehrfachvererbung durchführen können, dh Klassen, die auf mehr als eine Klasse übertragen werden können.
Nehmen wir ein einfaches Beispiel.
Angenommen, es gibt zwei Oberklassen der Klassen A und B mit denselben Methodennamen, aber unterschiedlichen Funktionen. Durch folgenden Code mit (erweitertem) Schlüsselwort ist eine Mehrfachvererbung nicht möglich.
Über Schnittstellen mit (implementiert) Schlüsselwort ist jedoch eine Mehrfachvererbung möglich.
quelle
Sie können Antwort von dieser Dokumentation finden Link
Wenn Mehrfachvererbung zulässig ist und Sie ein Objekt durch Instanziieren dieser Klasse erstellen, erbt dieses Objekt Felder von allen Superklassen der Klasse. Es wird zwei Probleme verursachen.
Was ist, wenn Methoden oder Konstruktoren aus verschiedenen Superklassen dasselbe Feld instanziieren?
Welche Methode oder welcher Konstruktor hat Vorrang?
Obwohl die mehrfache Vererbung von Status jetzt zulässig ist, können Sie sie dennoch implementieren
Mehrfachvererbung vom Typ : Fähigkeit einer Klasse, mehr als eine Schnittstelle zu implementieren.
Mehrfachvererbung der Implementierung (über Standardmethoden in Schnittstellen): Möglichkeit, Methodendefinitionen von mehreren Klassen zu erben
Weitere Informationen finden Sie in dieser verwandten SE-Frage:
Mehrdeutige Mehrdeutigkeit mit Schnittstelle
quelle
In C ++ kann eine Klasse (direkt oder indirekt) von mehr als einer Klasse erben, was als Mehrfachvererbung bezeichnet wird .
C # und Java beschränken Klassen jedoch auf eine einzelne Vererbung, die jede Klasse von einer einzelnen übergeordneten Klasse erbt.
Die Mehrfachvererbung ist eine nützliche Methode zum Erstellen von Klassen, die Aspekte zweier unterschiedlicher Klassenhierarchien kombinieren. Dies tritt häufig auf, wenn unterschiedliche Klassenframeworks in einer einzelnen Anwendung verwendet werden.
Wenn zwei Frameworks beispielsweise ihre eigenen Basisklassen für Ausnahmen definieren, können Sie mithilfe der Mehrfachvererbung Ausnahmeklassen erstellen, die mit beiden Frameworks verwendet werden können.
Das Problem bei der Mehrfachvererbung besteht darin, dass dies zu Mehrdeutigkeiten führen kann. Das klassische Beispiel ist, wenn eine Klasse von zwei anderen Klassen erbt, von denen jede von derselben Klasse erbt:
In diesem Beispiel wird das
flag
Datenelement durch definiertclass A
. Aberclass D
stammt vonclass B
und abclass C
, von denen beide abgeleitet sindA
, so dass im Wesentlichen zwei Kopien vonflag
verfügbar sind, da zwei Instanzen vonA
inD
der Klassenhierarchie sind. Welches möchten Sie einstellen? Der Compiler wird sich beschweren , dass der Verweis aufflag
inD
ist mehrdeutig . Eine Lösung besteht darin, die Referenz explizit zu disambiguieren:Ein weiterer Fix besteht darin, B und C als zu deklarieren
virtual base classes
bedeutet, dass nur eine Kopie von A in der Hierarchie vorhanden sein kann, wodurch Mehrdeutigkeiten beseitigt werden.Andere Komplexitäten bestehen bei Mehrfachvererbung, z. B. die Reihenfolge, in der die Basisklassen beim Erstellen eines abgeleiteten Objekts initialisiert werden, oder die Art und Weise, wie Mitglieder versehentlich vor abgeleiteten Klassen verborgen werden können. Um diese Komplexität zu vermeiden, beschränken sich einige Sprachen auf das einfachere Einzelvererbungsmodell.
Dies vereinfacht zwar die Vererbung erheblich, schränkt jedoch auch ihre Nützlichkeit ein, da nur Klassen mit einem gemeinsamen Vorfahren Verhaltensweisen gemeinsam nutzen können. Schnittstellen verringern diese Einschränkung etwas, indem sie Klassen in verschiedenen Hierarchien erlauben, gemeinsame Schnittstellen verfügbar zu machen, selbst wenn sie nicht durch gemeinsame Nutzung von Code implementiert werden.
quelle
Stellen Sie sich dieses Beispiel vor: Ich habe eine Klasse
Shape1
Es hat
CalcualteArea
Methode:Es gibt eine andere Klasse
Shape2
, die ebenfalls dieselbe Methode hatJetzt habe ich einen Kreis der Kinderklasse, der sowohl von Shape1 als auch von Shape2 abgeleitet ist.
Wenn ich nun ein Objekt für Circle erstelle und die Methode aufrufe, weiß das System nicht, welche Berechnungsflächenmethode aufgerufen werden soll. Beide haben die gleichen Signaturen. Der Compiler wird also verwirrt. Aus diesem Grund sind Mehrfachvererbungen nicht zulässig.
Es kann jedoch mehrere Schnittstellen geben, da Schnittstellen keine Methodendefinition haben. Auch wenn beide Schnittstellen dieselbe Methode haben, haben beide keine Implementierung und es wird immer eine Methode in der untergeordneten Klasse ausgeführt.
quelle