wake-up-neo.com

Unterschied zwischen Vererbung und Zusammensetzung

Sind Zusammensetzung und Vererbung gleich? Wenn ich das Kompositionsmuster implementieren möchte, wie kann ich das in Java tun?

166
gmhk

Sie sind absolut verschieden. Vererbung ist eine "is-a" - Beziehung. Komposition ist ein "has-a".

Sie erstellen eine Komposition, indem Sie eine Instanz einer anderen Klasse C als Feld Ihrer Klasse verwenden, anstatt C zu erweitern. Ein gutes Beispiel, wo die Komposition viel besser gewesen wäre als die Vererbung, ist Java.util.Stack, was derzeit Java.util.Vector erweitert. Dies wird jetzt als Fehler angesehen. Ein stack "is-NOT-a" - Vektor; Elemente dürfen nicht beliebig eingefügt und entfernt werden. Stattdessen hätte es Komposition sein sollen.

Leider ist es zu spät, um diesen Konstruktionsfehler zu korrigieren, da eine Änderung der Vererbungshierarchie die Kompatibilität mit vorhandenem Code beeinträchtigen würde. Wurde Stack anstelle von Vererbung verwendet, kann sie immer geändert werden, um eine andere Datenstruktur zu verwenden, ohne die API zu verletzen.

Ich empfehle Josh Blochs Buch Effective Java 2nd Edition

  • Punkt 16: Bevorzugung der Zusammensetzung gegenüber der Vererbung
  • Punkt 17: Design und Dokument zur Vererbung oder zum Verbot

Bei einem guten objektorientierten Design geht es nicht darum, vorhandene Klassen umfassend zu erweitern. Ihr erster Instinkt sollte es sein, stattdessen zu komponieren.


Siehe auch:

261

Zusammensetzung bedeutet HAS A
.__ Vererbung bedeutet IS A

Example: Auto hat einen Motor und Auto ist ein Automobile

In der Programmierung wird dies dargestellt als:

class Engine {} // The Engine class.

class Automobile {} // Automobile class which is parent to Car class.

class Car extends Automobile { // Car is an Automobile, so Car class extends Automobile class.
  private Engine engine; // Car has an Engine so, Car class has an instance of Engine class as its member.
}
170
codaddict

Wie kann Erbschaft gefährlich sein?

Nehmen wir ein Beispiel

public class X{    
   public void do(){    
   }    
}    
Public Class Y extends X{
   public void work(){    
       do();    
   }
}

1) Wie im obigen Code klar, hat die Klasse Y eine sehr starke Kopplung mit der Klasse X. Wenn sich in der Superklasse X etwas ändert, kann Y dramatisch brechen. Angenommen, Klasse X implementiert in Zukunft eine Methode, die mit der folgenden Signatur arbeitet

public int work(){
}

Die Änderung erfolgt in Klasse X, macht die Klasse Y jedoch nicht kompilierbar. SO Diese Art von Abhängigkeit kann bis zu einem beliebigen Level steigen und sehr gefährlich sein. Jedes Mal, wenn die Oberklasse nicht vollständig über den Code für alle Unterklassen und Unterklassen informiert ist, kann es sein, dass sie ständig bemerken, was in der Oberklasse geschieht. Daher müssen wir diese starke und unnötige Kopplung vermeiden.

Wie löst Komposition dieses Problem?

Schauen wir uns das gleiche Beispiel an

public class X{
    public void do(){
    }
}

Public Class Y{
    X x = new X();    
    public void work(){    
        x.do();
    }
}

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. Superklasse und Unterklasse sind jetzt sehr unabhängig voneinander. Die Klassen können frei Änderungen vornehmen, die in der Vererbungssituation gefährlich waren.

2) Zweitens sehr guter Vorteil der Zusammensetzung, indem sie die Flexibilität beim Aufruf von Methoden bietet, zum Beispiel:

class X implements R
{}
class Y implements R
{}

public class Test{    
    R r;    
}

In der Testklasse unter Verwendung der Referenz kann ich sowohl Methoden der X-Klasse als auch der Y-Klasse aufrufen. Diese Flexibilität war niemals in der Erbschaft vorhanden

3) Ein weiterer großer Vorteil: Unit Testing

public class X {
    public void do(){
    }
}

Public Class Y {
    X x = new X();    
    public void work(){    
        x.do();    
    }    
}

Wenn im obigen Beispiel der Status der x-Instanz nicht bekannt ist, kann er leicht mit einigen Testdaten simuliert werden, und alle Methoden können leicht getestet werden. Dies war bei der Vererbung überhaupt nicht möglich, da Sie stark von der Superklasse abhängig waren, um den Status der Instanz 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:

Public class Transaction {
    Banking b;
    public static void main(String a[])    
    {    
        b = new Deposit();    
        if(b.deposit()){    
            b = new Credit();
            c.credit();    
        }
    }
}

Gut zu wissen : 

  1. die Komposition wird zur Laufzeit leicht erreicht, während die Vererbung ihre Funktionen zur Kompilierzeit bereitstellt 

  2. komposition wird auch als HAS-A-Beziehung und Vererbung auch als IS-A-Beziehung bezeichnet

Machen Sie es sich zur Gewohnheit, die Komposition aus verschiedenen Gründen immer der Zusammensetzung vorzuziehen. 

27

Die von @Michael Rodrigues gegebene Antwort ist nicht korrekt (ich entschuldige mich, ich kann mich nicht direkt dazu äußern) und könnte zu Verwirrung führen. 

Schnittstellenimplementierung ist eine Form der Vererbung ... Wenn Sie eine Schnittstelle implementieren, erben Sie nicht nur alle Konstanten, sondern Sie verpflichten Ihr Objekt zu dem von der Schnittstelle angegebenen Typ. Es ist immer noch eine "is-a" Beziehung. Wenn ein Auto Fillable implementiert, ist das Auto "is-a" Fillable und kann in Ihrem Code verwendet werden, wo immer Sie ein Fillable verwenden würden. .

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 auf, im Gegensatz zu der "is-a" - Beziehung, die Sie herstellen wenn Sie Vererbung verwenden

Wenn ich also von den Auto-Beispielen in den anderen Fragen sagen wollte, dass ein Benzin-Tank "has-a" hat, würde ich die Zusammensetzung wie folgt verwenden:

public class Car {

private GasTank myCarsGasTank;

}

Hoffentlich klärt das alle Missverständnisse.

17
Kris

Inheritance bringt die Beziehung IS-A heraus. Composition bringt HAS-A-Relation ..__ hervor. Das Strategiemuster erklärt, dass Composition in Fällen verwendet werden sollte, in denen es Familien gibt, die ein bestimmtes Verhalten definieren.
Klassisches Beispiel für eine Entenklasse, die ein Flugverhalten implementiert.

public interface Flyable{
 public void fly();
}

public class Duck {
 Flyable fly;

 public Duck(){
  fly = new BackwardFlying();
 }
}

So können wir mehrere Klassen haben, die flyingeg implementieren:

public class BackwardFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies backward ");
  }
}
public class FastFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies 100 miles/sec");
  }
}

Wäre es für die Vererbung gewesen, hätten wir zwei verschiedene Vogelklassen, die die Fliegenfunktion immer wieder implementieren. Vererbung und Zusammensetzung sind also völlig verschieden.

14

Die Komposition ist so, wie sie sich anhört - Sie erstellen ein Objekt, indem Sie Teile einstecken.

EDITDer Rest dieser Antwort basiert irrtümlich auf der folgenden Prämisse.
Dies wird mit Schnittstellen erreicht.
Verwenden Sie beispielsweise das obige Beispiel Car,

Car implements iDrivable, iUsesFuel, iProtectsOccupants
Motorbike implements iDrivable, iUsesFuel, iShortcutThroughTraffic
House implements iProtectsOccupants
Generator implements iUsesFuel

Mit wenigen theoretischen Standardkomponenten können Sie Ihr Objekt aufbauen. Es ist dann Ihre Aufgabe zu beschreiben, wie eine House ihre Insassen schützt und wie eine Car ihre Insassen schützt.

Vererbung ist umgekehrt. Sie beginnen mit einem vollständigen (oder halbfertigen) Objekt und ersetzen oder überschreiben die verschiedenen Bits, die Sie ändern möchten.

Beispielsweise kann MotorVehicle mit einer Fuelable-Methode und einer Drive-Methode geliefert werden. Sie können die Kraftstoffmethode so belassen, wie sie ist, weil ein Motorrad und ein Auto gleich befüllt werden. Sie können jedoch die Drive-Methode außer Kraft setzen, da das Motorrad sehr unterschiedlich zu einer Car fährt.

Mit der Vererbung sind einige Klassen bereits vollständig implementiert, und andere verfügen über Methoden, die Sie überschreiben müssen. Mit Komposition ist dir nichts gegeben. (Sie können die Schnittstellen jedoch implementieren, indem Sie Methoden in anderen Klassen aufrufen, falls etwas passiert.).

Komposition wird als flexibler angesehen, denn wenn Sie über eine Methode wie iUsesFuel verfügen, können Sie eine Methode an anderer Stelle (eine andere Klasse, ein anderes Projekt) haben, 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. Interfaces schreiben vor, dass Klassen, die angeben, dass sie dieses Interface implementieren, tatsächlich die Methoden haben, um die es sich bei diesem Interface handelt. Zum Beispiel, 

iFuelable Interface:
   void AddSomeFuel()
   void UseSomeFuel()
   int  percentageFull()

dann kannst du woanders eine Methode haben

private void FillHerUp(iFuelable : objectToFill) {

   Do while (objectToFill.percentageFull() <= 100)  {

        objectToFill.AddSomeFuel();
   }

Seltsames Beispiel, aber es zeigt, dass diese Methode sich nicht darum kümmert, was sie füllt, weil das Objekt iUsesFuel implementiert, es kann gefüllt werden. Ende der Geschichte.

Wenn Sie stattdessen Inheritance verwendet haben, benötigen Sie unterschiedliche FillHerUp-Methoden, um mit MotorVehicles und Barbecues umzugehen, es sei denn, Sie hatten ein seltsames "ObjectThatUsesFuel" -Stammobjekt, von dem Sie erben können.

7

Sind Zusammensetzung und Vererbung gleich?

Sie sind nicht gleich. 

Composition : Damit kann eine Gruppe von Objekten wie eine einzelne Instanz eines Objekts behandelt werden. Der Zweck eines Verbunds besteht darin, Objekte in Baumstrukturen zu "zusammensetzen", um Teil-Ganz-Hierarchien darzustellen

Vererbung : Eine Klasse erbt Felder und Methoden von allen ihren Oberklassen, ob direkt oder indirekt. Eine Unterklasse kann Methoden, die sie erbt, überschreiben oder Felder oder Methoden verbergen, die sie erbt.

Wie kann ich das Kompositionsmuster in Java implementieren?

Wikipedia Artikel ist gut genug, um zusammengesetzte Muster in Java zu implementieren.

 enter image description here

Hauptteilnehmer:

Komponente:

  1. Ist die Abstraktion für alle Komponenten, auch für zusammengesetzte
  2. Deklariert die Schnittstelle für Objekte in der Komposition

Blatt:

  1. Repräsentiert Blattobjekte in der Komposition
  2. Implementiert alle Component -Methoden

Composite:

  1. Stellt eine zusammengesetzte Komponente dar (Komponente mit untergeordneten Elementen).
  2. Implementiert Methoden zur Manipulation von Kindern
  3. Implementiert alle Komponentenmethoden, indem sie im Allgemeinen an die untergeordneten Elemente delegiert werden

Codebeispiel zum Verständnis des Composite - Musters:

import Java.util.List;
import Java.util.ArrayList;

interface Part{
    public double getPrice();
    public String getName();
}
class Engine implements Part{
    String name;
    double price;
    public Engine(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Trunk implements Part{
    String name;
    double price;
    public Trunk(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Body implements Part{
    String name;
    double price;
    public Body(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Car implements Part{
    List<Part> parts;
    String name;

    public Car(String name){
        this.name = name;
        parts = new ArrayList<Part>();
    }
    public void addPart(Part part){
        parts.add(part);
    }
    public String getName(){
        return name;
    }
    public String getPartNames(){
        StringBuilder sb = new StringBuilder();
        for ( Part part: parts){
            sb.append(part.getName()).append(" ");
        }
        return sb.toString();
    }
    public double getPrice(){
        double price = 0;
        for ( Part part: parts){
            price += part.getPrice();
        }
        return price;
    }   
}

public class CompositeDemo{
    public static void main(String args[]){
        Part engine = new Engine("DiselEngine",15000);
        Part trunk = new Trunk("Trunk",10000);
        Part body = new Body("Body",12000);

        Car car = new Car("Innova");
        car.addPart(engine);
        car.addPart(trunk);
        car.addPart(body);

        double price = car.getPrice();

        System.out.println("Car name:"+car.getName());
        System.out.println("Car parts:"+car.getPartNames());
        System.out.println("Car price:"+car.getPrice());
    }

}

ausgabe:

Car name:Innova
Car parts:DiselEngine Trunk Body
Car price:37000.0

Erläuterung:

  1. Part ist ein Blatt
  2. Auto enthält viele Teile
  3. Dem Auto wurden verschiedene Teile des Autos hinzugefügt
  4. Der Preis von Auto = Summe von (Preis von jedem Teil)

Vor- und Nachteile von Zusammensetzung und Vererbung finden Sie unten.

Zusammensetzung lieber als Vererbung?

5
Ravindra babu

als ein anderes Beispiel, eine Autoklasse in Betracht zu ziehen, wäre dies eine gute Verwendung der Zusammensetzung, ein Auto würde einen Motor, ein Getriebe, Reifen, Sitze usw. "besitzen". Es würde keine dieser Klassen erweitern.

4
BlackICE

In einfachen Wortaggregationsmitteln hat eine Beziehung ..  

Zusammensetzung ist ein Sonderfall der Aggregation . In einer spezifischeren Weise wird eine beschränkte Aggregation als Komposition 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 Komposition zwischen Klasse und Studenten.  

Warum Aggregation verwenden

Wiederverwendbarkeit von Code

Wenn Aggregation verwenden

Die Wiederverwendung von Code lässt sich auch am besten durch Aggregation erreichen, wenn kein Relation-Schiff vorhanden ist

Vererbung

Vererbung ist eine Beziehung zwischen Eltern und Kind. Vererbung bedeutet, dass eine Beziehung besteht.

Vererbung in Java ist ein Mechanismus, bei dem ein Objekt alle Eigenschaften und Verhaltensweisen eines übergeordneten Objekts erhält.

Verwenden der Vererbung in Java 1 Wiederverwendbarkeit von Code 2 Zusätzliches Feature in untergeordneter Klasse sowie Methodenüberschreibung hinzufügen (damit Laufzeitpolymorphismus erzielt werden kann).

3
Keshav Gera

Vererbung zwischen zwei Klassen, wobei eine Klasse erweitert wird, eine andere Klasse eine " IS A " Beziehung herstellt. 

Composition am anderen Ende enthält eine Instanz einer anderen Klasse in Ihrer Klasse, die eine "Has A" - Beziehung aufbaut. Composition in Java ist hilfreich, da es die Mehrfachvererbung technisch vereinfacht.

3
John Wilson

In der Zusammensetzung besteht etwas aus verschiedenen Teilen und es hat eine starke Beziehung zu diesen Teilen. Wenn der Hauptteil stirbt und die anderen sterben, können sie kein eigenes Leben führen. Ein grobes Beispiel ist der menschliche Körper. Nimm das Herz heraus und alle anderen Teile sterben weg.

Vererbung ist, wo Sie etwas nehmen, was bereits existiert, und es verwenden. Es gibt keine starke Beziehung. Ein Mensch könnte das Vermögen seines Vaters erben, aber er kann darauf verzichten. 

Ich kenne Java nicht, daher kann ich kein Beispiel geben, aber ich kann die Konzepte erklären.

2
Robert Rocha

Obwohl sowohl Inheritance als auch Composition Wiederverwendbarkeit von Code bieten, besteht der Hauptunterschied zwischen Composition und Inheritance in Java darin, dass Composition die Wiederverwendung von Code ohne Erweiterung ermöglicht. Für Inheritance müssen Sie jedoch die Klasse für die 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 verwenden können, die nicht erweiterbar ist, Inheritance jedoch in solchen Fällen Code nicht wiederverwenden kann. Durch die Verwendung von Composition können Sie Code aus vielen Klassen wiederverwenden, da sie nur als Member-Variable deklariert sind. Mit Vererbung können Sie Code jedoch nur für eine Klasse wiederverwenden, da Sie in Java nur eine Klasse erweitern können, da in Java keine Mehrfachvererbung unterstützt wird . Sie können dies jedoch in C++ tun, da eine Klasse mehr als eine Klasse erweitern kann. Übrigens solltest du immer komposition gegenüber Vererbung in Java bevorzugenEs ist nicht nur ich, sondern sogar Joshua Bloch hat in seinem Buch vorgeschlagen

2
Nitin Pawar

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 beachtet die Tatsache, dass; In vererbung kann eine Änderung in der übergeordneten Klasse zu Problemen in der abgeleiteten Klasse führen, die diese erben.

Dort können Sie auch den Unterschied in der Darstellung sehen, wenn Sie eine UML für Vererbung oder Komposition verwenden.

http://www.javaworld.com/article/2076814/core-Java/inheritance-versus-composition--which-one-hould-you-choose-.html

1
aunte

Vererbung gegen Zusammensetzung.

Vererbung und Zusammensetzung werden zur Wiederverwendbarkeit und Erweiterung des Klassenverhaltens verwendet. 

Vererbungen werden hauptsächlich in einem Familienalgorithmus-Programmiermodell wie dem IS-A-Beziehungstyp verwendet, das eine ähnliche Art von Objekt bedeutet. Beispiel.

  1. Duster ist ein Auto 
  2. Safari ist ein Auto

Diese gehören zur Autofamilie.

Die Komposition stellt den HAS-A-Beziehungstyp dar. Sie zeigt die Fähigkeit eines Objekts wie Duster hat fünf Gänge, Safari hat vier Gänge usw. Wenn wir die Fähigkeiten einer vorhandenen Klasse erweitern möchten, verwenden Sie die Komposition. Beispiel benötigen wir Um ein weiteres Zahnrad in einem Duster-Objekt hinzuzufügen, müssen Sie ein weiteres Zahnrad-Objekt erstellen und es zum Duster-Objekt zusammenstellen.

Wir sollten die Änderungen in der Basisklasse nicht vornehmen, es sei denn, alle abgeleiteten Klassen benötigten diese Funktionalität. 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 Funktionalität in Klasse A hinzufügen, ist sie für alle Unterklassen verfügbar, selbst wenn die Klassen 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 diese der erforderlichen Klasse zuordnen ( hier ist Klasse B). 

Unten ist das Beispiel:

          // This is a base class
                 public abstract class Car
                    {
                       //Define prototype
                       public abstract void color();
                       public void Gear() {
                           Console.WriteLine("Car has a four Gear");
                       }
                    }


           // Here is the use of inheritence
           // This Desire class have four gears.
          //  But we need to add one more gear that is Neutral gear.

          public class Desire : Car
                   {
                       Neutral obj = null;
                       public Desire()
                       {
     // Here we are incorporating neutral gear(It is the use of composition). 
     // Now this class would have five gear. 

                           obj = new Neutral();
                           obj.NeutralGear();
                       }

                       public override void color()
                       {
                           Console.WriteLine("This is a white color car");
                       }

                   }


             // This Safari class have four gears and it is not required the neutral
             //  gear and hence we don't need to compose here.

                   public class Safari :Car{
                       public Safari()
                       { }

                       public override void color()
                       {
                           Console.WriteLine("This is a red color car");
                       }


                   }

   // This class represents the neutral gear and it would be used as a composition.

   public class Neutral {
                      public void NeutralGear() {
                           Console.WriteLine("This is a Neutral Gear");
                       }
                   }
1

Inheritenz bedeutet, die gesamte Funktionalität einer Klasse wiederzuverwenden. Hier muss meine Klasse alle Methoden der Superklasse verwenden, und meine Klasse wird mit der Superklasse verknüpft, und Code wird in beiden Klassen im Fall der Erbschaft dupliziert.

All diese Probleme können wir überwinden, wenn wir die 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 erwarten, können wir dieses Attribut verwenden. 

0
Vikas Kapadiya

Komposition bedeutet, ein Objekt für eine Klasse zu erstellen, die eine Beziehung zu dieser bestimmten Klasse hat.

Eine Vererbung ist die vorhergehende Klasse mit der erweiterten Funktion. Dies bedeutet, dass diese neue Klasse die alte Klasse mit einigen erweiterten Funktionen ist .__ Angenommen, Student ist Student, aber alle Studenten sind Menschen. Es besteht also eine Beziehung zum Schüler und zum Menschen. Dies ist Vererbung.

0
HM Nayem

Nein, beide sind unterschiedlich. Zusammensetzung folgt "HAS-A" Beziehung und Vererbung folgt "IS-A" Beziehung. Bestes Beispiel für die Zusammensetzung war das strategische Muster.

0
Ranga Reddy

Kompostion

  • ist eine Möglichkeit, einfache Objekte oder Datentypen zu komplexeren zu kombinieren
  • Eine Kompositionsbeziehung besteht zwischen zwei Klassen, wenn ein Klassenfeld aus einer anderen Klasse besteht
  • Wird als has-a Beziehung bezeichnet

Vererbung

  • An der Oberfläche ist Vererbung ein Code Wiederverwendung
  • wir können Code, der bereits in einer überschaubaren Weise geschrieben ist, erweitern.
  • Vererbung ist mehr, es unterstützt Polymorphismus auf Sprachebene!
  • Informationen werden in einer hierarchischen Reihenfolge verwaltbar gemacht
  • Mit der Vererbung kann eine neue Klasse als Baustein aus vorhandenen Klassen abgeleitet werden
  • Neue Klasse Erbt Eigenschaften und Methoden der vorhandenen Klasse
  • verwenden von Erweitert und Implementiert Keywords
  • Es gibt eine Klassenhierarchie (Direkt/Indirekt/Einfach/Mehrfach)
0