1984 Stimmen

Bevorzugen Sie Komposition statt Vererbung?

Warum Komposition der Vererbung vorziehen? Welche Kompromisse gibt es für jeden Ansatz? Wann sollten Sie Vererbung der Komposition vorziehen?

6 Stimmen

6 Stimmen

In einem Satz Vererbung ist öffentlich, wenn Sie eine öffentliche Methode haben und Sie ändern es ändert die veröffentlichte api. wenn Sie Zusammensetzung haben und das Objekt komponiert hat sich geändert, müssen Sie nicht Ihre veröffentlichte api ändern.

6voto

Jon Limjap Punkte 92084

Abgesehen von den is a/has a-Überlegungen muss man auch die "Tiefe" der Vererbung berücksichtigen, die das Objekt durchlaufen muss. Alles, was mehr als fünf oder sechs Vererbungsebenen tief ist, kann zu unerwarteten Casting- und Boxing/Unboxing-Problemen führen, und in diesen Fällen kann es sinnvoll sein, das Objekt stattdessen zu komponieren.

6voto

Amir Aslam Punkte 371

Wenn Sie eine ist- Beziehung zwischen zwei Klassen (z. B. Hund ist ein Hund), so wird die Vererbung eingesetzt.

Andererseits, wenn Sie hat-a oder eine adjektivische Beziehung zwischen zwei Klassen (Schüler hat Kurse) oder (Lehrer studiert Kurse), haben Sie Komposition gewählt.

0 Stimmen

Sie sagten Vererbung und Vererbung. Meinen Sie nicht Vererbung und Zusammensetzung?

0 Stimmen

Nein, das müssen Sie nicht. Sie können genauso gut eine Hundeschnittstelle definieren und sie von jedem Hund implementieren lassen, und Sie werden am Ende mehr SOLID-Code haben.

5voto

Y.S Punkte 29133

Ein einfacher Weg, dies zu verstehen, wäre, dass Vererbung verwendet werden sollte, wenn Sie ein Objekt Ihrer Klasse benötigen, das dieselbe Schnittstelle als ihre Elternklasse, so dass sie als Objekt der Elternklasse behandelt werden kann (Upcasting). Außerdem würden Funktionsaufrufe auf ein Objekt einer abgeleiteten Klasse überall im Code gleich bleiben, aber die spezifische aufzurufende Methode würde zur Laufzeit bestimmt (d.h. die Low-Level Umsetzung abweicht, ist die hochrangige Schnittstelle bleibt gleich).

Komposition sollte verwendet werden, wenn die neue Klasse nicht dieselbe Schnittstelle haben muss, d. h. wenn Sie bestimmte Aspekte der Implementierung der Klasse verbergen wollen, die der Benutzer dieser Klasse nicht kennen muss. Komposition ist also eher eine Unterstützung für Verkapselung (d.h. Verbergen der Implementierung), während die Vererbung dazu gedacht ist, die Abstraktion (d. h. eine vereinfachte Darstellung von etwas, in diesem Fall der dieselbe Schnittstelle für eine Reihe von Typen mit unterschiedlichen Interna).

0 Stimmen

+1 für die Erwähnung der Schnittstelle. Ich verwende diesen Ansatz häufig, um bestehende Klassen zu verbergen und meine neue Klasse durch Mocking Out des für die Komposition verwendeten Objekts richtig unit-testbar zu machen. Dies erfordert, dass der Eigentümer des neuen Objekts ihm stattdessen die Kandidaten-Elternklasse übergibt.

4voto

Ravindra babu Punkte 45577

Auch wenn die Komposition bevorzugt wird, möchte ich folgende Vorteile hervorheben Vererbung und Nachteile von Zusammensetzung .

Vorteile der Vererbung:

  1. Sie schafft eine logische " IS A" Beziehung. Wenn Auto y Lkw sind zwei Arten von Fahrzeug ( Basisklasse), Unterklasse IS A Basisklasse.

    d.h.

    Auto ist ein Fahrzeug

    Lkw ist ein Fahrzeug

  2. Mit Vererbung können Sie eine Fähigkeit definieren/verändern/erweitern

    1. Die Basisklasse bietet keine Implementierung und die Unterklasse muss die komplette Methode überschreiben (abstrakt) => Sie können einen Vertrag implementieren
    2. Die Basisklasse bietet eine Standardimplementierung und die Unterklasse kann das Verhalten ändern => Sie können den Vertrag neu definieren
    3. Die Unterklasse fügt der Implementierung der Basisklasse eine Erweiterung hinzu, indem sie als erste Anweisung super.methodName() aufruft => Sie können einen Vertrag verlängern
    4. Die Basisklasse definiert die Struktur des Algorithmus und die Unterklasse überschreibt einen Teil des Algorithmus => _Sie können implementieren Vorlage_Methode ohne Änderung des Skeletts der Basisklasse_

Nachteile der Komposition:

  1. Bei der Vererbung kann die Unterklasse die Methode der Basisklasse direkt aufrufen, obwohl sie die Methode der Basisklasse nicht implementiert, weil sie IS A Beziehung. Wenn Sie Komposition verwenden, müssen Sie Methoden in der Containerklasse hinzufügen, um die API der enthaltenen Klasse offenzulegen

z.B. Wenn Auto enthält Fahrzeug und wenn Sie den Preis der Auto die definiert wurde in Fahrzeug wird Ihr Code folgendermaßen aussehen

class Vehicle{
     protected double getPrice(){
          // return price
     }
} 

class Car{
     Vehicle vehicle;
     protected double getPrice(){
          return vehicle.getPrice();
     }
}

0 Stimmen

Ich denke, das beantwortet die Frage nicht

0 Stimmen

Sie können sich die Frage von OP noch einmal ansehen. Ich habe angesprochen: Welche Kompromisse gibt es für jeden Ansatz?

1 Stimmen

Wie Sie bereits erwähnt haben, sprechen Sie nur über die "Vorteile der Vererbung und die Nachteile der Zusammensetzung", nicht aber über die Kompromisse für JEDEN Ansatz oder die Fälle, in denen Sie einen Ansatz dem anderen vorziehen sollten

4voto

Shelby Moore III Punkte 5909

Die Subtypisierung ist angemessen und leistungsfähiger, wenn die Invarianten können aufgezählt werden oder die Funktionskomposition für die Erweiterbarkeit verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X