Sind Zusammensetzung und Vererbung gleich? Wie kann ich das in Java implementieren, wenn ich das Kompositionsmuster implementieren möchte?
java
oop
inheritance
composition
gmhk
quelle
quelle
Antworten:
Sie sind absolut unterschiedlich. Vererbung ist eine "ist-eine" Beziehung. Zusammensetzung ist ein "has-a" .
Sie komponieren, indem Sie eine Instanz einer anderen Klasse
C
als Feld Ihrer Klasse verwenden, anstatt sie zu erweiternC
. Ein gutes Beispiel, bei dem die Komposition viel besser gewesen wäre als die Vererbung, istjava.util.Stack
das derzeit erweitertejava.util.Vector
. Dies wird jetzt als Fehler angesehen. Ein Stapelvektor "ist NICHT ein" ; Es sollte Ihnen nicht gestattet sein, Elemente willkürlich einzufügen und zu entfernen. Es hätte stattdessen Komposition sein sollen.Leider ist es zu spät, um diesen Entwurfsfehler zu beheben, da eine Änderung der Vererbungshierarchie die Kompatibilität mit vorhandenem Code beeinträchtigen würde. Wenn
Stack
Komposition anstelle von Vererbung verwendet wurde, kann sie jederzeit geändert werden, um eine andere Datenstruktur zu verwenden, ohne die API zu verletzen .Ich kann Josh Blochs Buch Effective Java 2nd Edition nur empfehlen
Bei einem guten objektorientierten Design geht es nicht darum, vorhandene Klassen großzügig zu erweitern. Ihr erster Instinkt sollte sein, stattdessen zu komponieren.
Siehe auch:
quelle
Zusammensetzung bedeutet
HAS A
Vererbung bedeutet
IS A
Example
: Auto hat einen Motor und Auto ist ein AutomobilIn der Programmierung wird dies dargestellt als:
quelle
:-/
type
Feld vom Typ habenEnum
Wie gefährlich kann Vererbung sein?
Nehmen wir ein Beispiel
1) Wie im obigen Code klar, hat Klasse Y eine sehr starke Kopplung mit Klasse X. Wenn sich in der Oberklasse X etwas ändert, kann Y dramatisch brechen. Angenommen, Klasse X implementiert in Zukunft eine Methodenarbeit mit der folgenden Signatur
Änderungen werden in Klasse X vorgenommen, aber Klasse Y wird nicht kompilierbar. SO kann diese Art von Abhängigkeit bis zu jeder Ebene gehen und es kann sehr gefährlich sein. Jedes Mal, wenn die Oberklasse möglicherweise nicht die volle Sichtbarkeit des Codes in allen Unterklassen hat und die Unterklasse möglicherweise ständig bemerkt, was in der Oberklasse passiert. Wir müssen also diese starke und unnötige Kopplung vermeiden.
Wie löst die Komposition dieses Problem?
Sehen wir uns das gleiche Beispiel an
Hier erstellen wir eine Referenz der X-Klasse in der Y-Klasse und rufen die Methode der X-Klasse auf, indem wir eine Instanz der X-Klasse erstellen. Jetzt ist all diese starke Kopplung weg. Oberklasse und Unterklasse sind jetzt sehr unabhängig voneinander. Klassen können frei Änderungen vornehmen, die in der Vererbungssituation gefährlich waren.
2) Zweitens ein sehr guter Vorteil der Komposition, da sie Flexibilität beim Aufrufen von Methoden bietet, zum Beispiel:
In der Testklasse mit der Referenz r kann ich sowohl Methoden der X-Klasse als auch der Y-Klasse aufrufen. Diese Flexibilität war bei der Vererbung nie vorhanden
3) Ein weiterer großer Vorteil: Unit Testing
Wenn im obigen Beispiel der Status der x-Instanz nicht bekannt ist, kann er mithilfe einiger Testdaten leicht nachgebildet werden, und alle Methoden können problemlos getestet werden. Dies war bei der Vererbung überhaupt nicht möglich, da Sie stark von der Oberklasse abhängig waren, um den Instanzstatus abzurufen und eine Methode auszuführen.
4) Ein weiterer guter Grund, warum wir Vererbung vermeiden sollten, ist, dass Java keine Mehrfachvererbung unterstützt.
Nehmen wir ein Beispiel, um dies zu verstehen:
Gut zu wissen :
Die Komposition ist zur Laufzeit leicht zu erreichen, während die Vererbung ihre Funktionen zur Kompilierungszeit bereitstellt
Zusammensetzung wird auch als HAS-A-Beziehung bezeichnet, und Vererbung wird auch als IS-A-Beziehung bezeichnet
Machen Sie es sich also zur Gewohnheit, aus verschiedenen oben genannten Gründen immer die Komposition der Vererbung vorzuziehen.
quelle
Die Antwort von @Michael Rodrigues ist nicht korrekt (ich entschuldige mich; ich kann nicht direkt kommentieren) und könnte zu Verwirrung führen.
Die Schnittstellenimplementierung ist eine Form der Vererbung . Wenn Sie eine Schnittstelle implementieren, erben Sie nicht nur alle Konstanten, sondern verpflichten Ihr Objekt zu dem von der Schnittstelle angegebenen Typ. Es ist immer noch eine " ist-eine " Beziehung. Wenn ein Auto implementiert Fillable , das Auto „ ist-a “ Fillable und kann in Ihrem Code verwendet werden , wo auch immer Sie verwenden würden Fillable .
Die Zusammensetzung unterscheidet sich grundlegend von der Vererbung. Wenn Sie Komposition verwenden, stellen Sie (wie in den anderen Antworten angegeben) eine " has-a " -Beziehung zwischen zwei Objekten her, im Gegensatz zu der " is-a " -Beziehung, die Sie bei Verwendung der Vererbung herstellen .
Wenn ich also anhand der Autobeispiele in den anderen Fragen sagen möchte, dass ein Auto einen Gastank hat , würde ich die Zusammensetzung wie folgt verwenden:
Hoffentlich klärt das Missverständnisse auf.
quelle
Vererbung bringt IS-A- Beziehung hervor. Die Zusammensetzung bringt die HAS-A-Beziehung hervor . Das Strategiemuster erklärt, dass die Zusammensetzung in Fällen verwendet werden sollte, in denen es Familien von Algorithmen gibt, die ein bestimmtes Verhalten definieren.
Ein klassisches Beispiel für eine Entenklasse, die ein Flugverhalten implementiert.
Somit können wir mehrere Klassen haben, die das Fliegen implementieren, z.
Wäre es eine Vererbung gewesen, hätten wir zwei verschiedene Vogelklassen, die die Fliegenfunktion immer wieder implementieren. Vererbung und Zusammensetzung sind also völlig unterschiedlich.
quelle
Komposition ist so, wie es sich anhört - Sie erstellen ein Objekt, indem Sie Teile einstecken.
BEARBEITEN Der Rest dieser Antwort basiert fälschlicherweise auf der folgenden Prämisse.
Dies wird mit Schnittstellen erreicht.
Verwenden Sie
Car
beispielsweise das obige Beispiel:Mit ein paar theoretischen Standardkomponenten können Sie Ihr Objekt aufbauen. Es ist dann Ihre Aufgabe, anzugeben, wie ein
House
seine Insassen schützt und wie einCar
seine Insassen schützt.Vererbung ist wie umgekehrt. Sie beginnen mit einem vollständigen (oder halbfertigen) Objekt und ersetzen oder überschreiben die verschiedenen Bits, die Sie ändern möchten.
Zum Beispiel
MotorVehicle
kann mit einerFuelable
Methode undDrive
Methode kommen. Sie können die Kraftstoffmethode so lassen, wie sie ist, weil es dasselbe ist, ein Motorrad und ein Auto zu tanken, aber Sie können dieDrive
Methode überschreiben , weil das Motorrad ganz anders fährt als einCar
.Bei der Vererbung sind einige Klassen bereits vollständig implementiert, andere verfügen über Methoden, die Sie überschreiben müssen. Mit Komposition wird dir nichts gegeben. (Sie können die Schnittstellen jedoch implementieren, indem Sie Methoden in anderen Klassen aufrufen, wenn zufällig etwas herumliegt.)
Die Komposition wird als flexibler angesehen, denn wenn Sie eine Methode wie iUsesFuel haben, können Sie eine andere Methode (eine andere Klasse, ein anderes Projekt) verwenden, die sich nur um den Umgang mit Objekten kümmert, die betankt werden können, unabhängig davon, ob es sich um ein Auto handelt. Boot, Herd, Grill usw. Schnittstellen schreiben vor, dass Klassen, die sagen, dass sie diese Schnittstelle implementieren, tatsächlich die Methoden haben, um die es bei dieser Schnittstelle geht. Beispielsweise,
dann können Sie eine Methode woanders haben
Seltsames Beispiel, aber es zeigt, dass es dieser Methode egal ist, was sie füllt, da das Objekt implementiert
iUsesFuel
, es kann gefüllt werden. Ende der Geschichte.Wenn Sie stattdessen Vererbung verwenden würden, würden Sie verschiedene
FillHerUp
Methoden benötigen , um mitMotorVehicles
und umzugehenBarbecues
, es sei denn, Sie hätten ein ziemlich seltsames "ObjectThatUsesFuel" -Basisobjekt, von dem Sie erben könnten.quelle
ThisCase
und nicht in geschrieben werdencamelCase
. Daher ist es am besten, Ihre SchnittstellenIDrivable
usw. zu benennen . Möglicherweise benötigen Sie das "I" nicht, wenn Sie alle Ihre Schnittstellen korrekt in einem Paket gruppieren.Sie sind nicht gleich.
Zusammensetzung : Damit kann eine Gruppe von Objekten wie eine einzelne Instanz eines Objekts behandelt werden. Die Absicht eines Verbunds ist es, Objekte in Baumstrukturen zu "komponieren", um Teil-Ganz-Hierarchien darzustellen
Vererbung : Eine Klasse erbt Felder und Methoden von allen direkten oder indirekten Oberklassen. Eine Unterklasse kann von ihr geerbte Methoden überschreiben oder von ihr geerbte Felder oder Methoden ausblenden.
Der Wikipedia- Artikel ist gut genug, um zusammengesetzte Muster in Java zu implementieren.
Hauptteilnehmer:
Komponente :
Blatt :
Zusammengesetzt :
Codebeispiel zum Verständnis des zusammengesetzten Musters:
Ausgabe:
Erläuterung:
Beziehen Sie sich auf die folgende Frage für Vor- und Nachteile der Zusammensetzung und Vererbung.
Komposition lieber als Vererbung?
quelle
Betrachten Sie als weiteres Beispiel eine Fahrzeugklasse. Dies wäre eine gute Verwendung der Zusammensetzung. Ein Auto hätte einen Motor, ein Getriebe, Reifen, Sitze usw. Es würde keine dieser Klassen erweitern.
quelle
Bei der Komposition besteht etwas aus verschiedenen Teilen und es besteht eine starke Beziehung zu diesen Teilen. Wenn der Hauptteil stirbt, sterben auch die anderen, sie können kein eigenes Leben führen. Ein grobes Beispiel ist der menschliche Körper. Nehmen Sie das Herz heraus und alle anderen Teile sterben ab.
Bei der Vererbung nehmen Sie einfach etwas, das bereits vorhanden ist, und verwenden es. Es gibt keine starke Beziehung. Ein Mensch könnte den Nachlass seines Vaters erben, aber er kann darauf verzichten.
Ich kenne Java nicht, daher kann ich kein Beispiel angeben, aber ich kann die Konzepte erläutern.
quelle
Die Vererbung zwischen zwei Klassen, wobei eine Klasse eine andere Klasse erweitert, stellt eine " IS A " -Beziehung her.
Die Komposition am anderen Ende enthält eine Instanz einer anderen Klasse in Ihrer Klasse, die die Beziehung " Hat A " herstellt. Die Komposition in Java ist nützlich, da sie die Mehrfachvererbung technisch erleichtert.
quelle
In einfachen Worten bedeutet Aggregation, dass eine Beziehung besteht.
Die Zusammensetzung ist ein Sonderfall der Aggregation . Genauer gesagt wird eine eingeschränkte Aggregation als Zusammensetzung bezeichnet. Wenn ein Objekt das andere Objekt enthält und das enthaltene Objekt ohne das Vorhandensein eines Containerobjekts nicht existieren kann, wird es als Komposition bezeichnet. Beispiel: Eine Klasse enthält Schüler. Ein Schüler kann ohne Klasse nicht existieren. Es gibt eine Komposition zwischen Klasse und Schülern.
Warum Aggregation verwenden?
Wiederverwendbarkeit des Codes
Bei Verwendung der Aggregation
Die Wiederverwendung von Code wird auch am besten durch Aggregation erreicht, wenn kein Beziehungsschiff vorhanden ist
Erbe
Vererbung ist eine Eltern-Kind-Beziehung Vererbung bedeutet, ist eine Beziehung
Die Vererbung in Java ist ein Mechanismus, bei dem ein Objekt alle Eigenschaften und Verhaltensweisen des übergeordneten Objekts erfasst.
Verwenden der Vererbung in Java 1 Code Reusability. 2 Fügen Sie zusätzliche Funktionen in der untergeordneten Klasse sowie das Überschreiben von Methoden hinzu (damit Laufzeitpolymorphismus erzielt werden kann).
quelle
Obwohl sowohl Vererbung als auch Komposition die Wiederverwendbarkeit von Code bieten, besteht der Hauptunterschied zwischen Komposition und Vererbung in Java darin, dass Komposition die Wiederverwendung von Code ermöglicht, ohne ihn zu erweitern. Für Vererbung müssen Sie die Klasse jedoch für jede Wiederverwendung von Code oder Funktionalität erweitern. Ein weiterer Unterschied, der sich aus dieser Tatsache ergibt, besteht darin, dass Sie mit Composition Code auch für die letzte Klasse wiederverwenden können, die nicht erweiterbar ist, aber Inheritance kann Code in solchen Fällen nicht wiederverwenden. Mit Composition können Sie auch Code aus vielen Klassen wiederverwenden, da diese nur als Mitgliedsvariable deklariert sind. Mit Inheritance können Sie jedoch Code aus nur einer Klasse wiederverwenden, da Sie in Java nur eine Klasse erweitern können, da in Java die Mehrfachvererbung nicht unterstützt wird . Sie können dies jedoch in C ++ tun, da dort eine Klasse mehr als eine Klasse erweitern kann. Übrigens sollten Sie immerlieber Komposition als Vererbung in Java , es ist nicht nur ich, sondern sogar Joshua Bloch hat in seinem Buch vorgeschlagen
quelle
Ich denke, dieses Beispiel erklärt deutlich die Unterschiede zwischen Vererbung und Zusammensetzung .
In diesem Beispiel wird das Problem durch Vererbung und Zusammensetzung gelöst. Der Autor achtet darauf, dass; Bei der Vererbung kann eine Änderung der Oberklasse Probleme in der abgeleiteten Klasse verursachen, die sie erbt.
Dort können Sie auch den Unterschied in der Darstellung sehen, wenn Sie eine UML für die Vererbung oder Komposition verwenden.
http://www.javaworld.com/article/2076814/core-java/inheritance-versus-composition--which-one-should-you-choose-.html
quelle
Vererbungen gegen Zusammensetzung.
Vererbungen und Zusammensetzung werden beide zur Wiederverwendbarkeit und Erweiterung des Klassenverhaltens verwendet.
Vererbungen, die hauptsächlich in einem Familienalgorithmus-Programmiermodell wie dem IS-A-Beziehungstyp verwendet werden, bedeuten eine ähnliche Art von Objekt. Beispiel.
Diese gehören zur Autofamilie.
Die Zusammensetzung stellt den HAS-A-Beziehungstyp dar. Sie zeigt die Fähigkeit eines Objekts wie Duster mit fünf Gängen, Safari mit vier Gängen usw. Wann immer wir die Fähigkeit einer vorhandenen Klasse erweitern müssen, verwenden Sie die Komposition. Beispiel: Wir müssen dem Duster-Objekt ein weiteres Zahnrad hinzufügen, dann müssen wir ein weiteres Zahnradobjekt erstellen und es zum Duster-Objekt zusammensetzen.
Wir sollten die Änderungen in der Basisklasse erst vornehmen, wenn alle abgeleiteten Klassen diese Funktionalität benötigen. Für dieses Szenario sollten wir Composition verwenden
Klasse A Abgeleitet von Klasse B.
Klasse A abgeleitet von Klasse C.
Klasse A abgeleitet von Klasse D.
Wenn wir eine Funktionalität in Klasse A hinzufügen, steht sie allen Unterklassen zur Verfügung, auch wenn Klasse C und D diese Funktionalität nicht benötigen. Für dieses Szenario müssen wir eine separate Klasse für diese Funktionalität erstellen und sie für die erforderliche Klasse zusammenstellen ( hier ist Klasse B).
Unten ist das Beispiel:
quelle
Komposition bedeutet, ein Objekt für eine Klasse zu erstellen, die eine Beziehung zu dieser bestimmten Klasse hat. Angenommen, der Schüler hat eine Beziehung zu den Konten.
Eine Vererbung ist, dass dies die vorherige Klasse mit der erweiterten Funktion ist. Das heißt, diese neue Klasse ist die alte Klasse mit einigen erweiterten Funktionen. Angenommen, Student ist Student, aber alle Studenten sind Menschen. Es besteht also eine Beziehung zwischen Schüler und Mensch. Das ist Vererbung.
quelle
Nein, beide sind unterschiedlich. Die Zusammensetzung folgt der Beziehung "HAS-A" und die Vererbung der Beziehung "IS-A". Bestes Beispiel für die Komposition war das strategische Muster.
quelle
Vererbung bedeutet, die gesamte Funktionalität einer Klasse wiederzuverwenden. Hier muss meine Klasse alle Methoden der Superklasse verwenden, und meine Klasse wird mit der Superklasse gekoppelt, und der Code wird im Falle einer Vererbung in beiden Klassen dupliziert.
Aber wir können all diese Probleme überwinden, wenn wir Komposition verwenden, um mit einer anderen Klasse zu sprechen. Komposition deklariert ein Attribut einer anderen Klasse in meiner Klasse, mit der wir sprechen möchten. und welche Funktionalität wir von dieser Klasse wollen, können wir mit diesem Attribut erhalten.
quelle