2016-12-08 3 views
0

Der folgende Absatz ist zitiert aus dem Buch "Thinking in Java" von Bruce Eckel.Vorteile der Zusammensetzung über die Vererbung in Java

Komposition ist sehr flexibel. Die Mitgliedsobjekte Ihrer neuen Klasse sind in der Regel privat, sodass sie für die Client-Programmierer, die die Klasse verwenden, nicht zugänglich sind. Dadurch können Sie diese Mitglieder ändern, ohne den vorhandenen Clientcode zu stören. Sie können die Mitgliedsobjekte auch zur Laufzeit ändern, um das Verhalten Ihres Programms dynamisch zu ändern. Vererbung, die als nächstes beschrieben wird, hat diese Flexibilität nicht, da der Compiler kompilierungszeitliche Einschränkungen für Klassen setzen muss, die mit der Vererbung erstellt wurden.

Ich verstehe nicht, wie das Mitglied Objekt dynamisch geändert werden kann, und wie es ein Vorteil gegenüber Vererbung ist. Konnte jemand dies bitte erklären

+1

Mitgliederobjekte sind über Referenzfelder verfügbar, und wenn sie veränderbar sind, können Sie sie mit einer Zuweisung ändern, d. H. '=' –

+0

Können Sie bitte ein Codebeispiel angeben –

+0

Warum der Downvote? –

Antwort

6

Wenn Ihre Klasse ArrayList erweitert, hat ein Benutzer Ihrer Klasse Zugriff auf alle öffentlichen Methoden von ArrayList. Sie können Ihre Klasse nicht ändern, um LinkedList zu erweitern, da dies den vorhandenen Code beschädigen kann.

public class Inheritence extends ArrayList<String> 
{ 
    // here your class depends on ArrayList implementation 
} 

Wenn auf der anderen Seite, Ihre Klasse ein eigenes Element, das hat Typ ist List, können die Benutzer Ihrer Klasse diese Methoden nicht direkt dieses Mitglied nennen. Und Sie können in der Laufzeit entscheiden, ob Sie diesem Member eine ArrayList Instanz zuweisen oder eine andere List Implementierung zuweisen (LinkedList oder etwas anderes).

public class Composition 
{ 
    private List<String> member; 

    public Composition() 
    { 
     // here you decide the type of your member during runtime 
     if (someCondition) { 
      member = new ArrayList<String>(); 
     } else { 
      member = new LinkedList<String>(); 
     } 
    } 
} 
1

Wenn Sie Vererbung verwenden, sehen Sie kaum das ganze Bild und Sie müssen den Code Hölle viel studieren zu können, verstehen, was los ist. Wenn Sie ein kleines Ding in der Elternklasse ändern, haben Sie Schwierigkeiten. Was ist mit all den Nachkommen? Hat sich diese Veränderung auf sie ausgewirkt?

Und auch prüfen, testen. Elternklasse kann nicht getrennt werden, Sie müssen alles testen und die Tests sind kompliziert und oft überhaupt nicht gemacht, weil der Aufwand einfach zu groß ist, um Tests sinnvoll zu machen.

Auf der anderen Seite, wenn Sie Komposition verwenden, können Sie einfach Funktionen trennen, können Sie Dependency Injection verwenden, wenn Sie Code anderer Leute lesen, können Sie sich auf kleinere Funktionalität konzentrieren. Wenn Klassen höherer Ebenen, die Komposition verwenden, kleinere Funktionen durch andere Implementierungen ersetzen müssen, dann ist das viel einfacher, weil Sie viel besser wissen, was im Code passiert. Der verstreute Code in mehreren Vererbungsebenen ist nicht eingekapselt und oft völlig unlesbar.

Vererbung ist auch gefährlich. Angenommen, Sie möchten beispielsweise zählen, wie viele Elemente Sie zu HashSet hinzugefügt haben. Sie können die Methoden add und addAll überschreiben, aber Sie wissen nicht, ob addAll die Methode add für jedes Element aufruft oder nicht. Siehe hierzu example

Um Ihre ursprüngliche Frage zu beantworten - Sie können das innere Objekt von einem Konstruktor oder Setter übergeben.

2

Die breitere Sichtweise auf Komposition und Vererbung suchen ist, die Zusammensetzung ist eine Design-Technik has-a Beziehung zu implementieren, während Vererbung ist eine Technik is-a Beziehung zu implementieren. Gehen wir in die Objektorientierungsperspektive, um dies besser zu verstehen.

Wenn ich sage, Dogist einMammal und Snakeist einReptile aber beide sind Animals, Das Design wie sein kann, sollte es eine Superklasse namens genannt Animal und zwei Kind Klassen Mammal und Reptile die Dog und Snake sollte erweitert werden. Der entsprechende Code lautet wie folgt:

public abstract class Animal { 
    public abstract void move(); 
    public abstract void sleep(); 
    public abstract void reproduce(); 

} 

Jedes Tier kann diese drei Aktionen ausführen.

public abstract class Mammal extends Animal{ 
    @Override 
    public void reproduce(){ 
     System.out.println("Gives birth!!"); 
    } 

} 

public abstract class Reptile extends Animal{ 
    @Override 
    public void reproduce(){ 
     System.out.println("Lays Eggs!!"); 
    } 
} 

Alle Säugetiere/Reptilien werden diese definierte Funktion in üblicher Weise ausführen.

public class Dog extends Mammal{ 

    @Override 
    public void move() { 
     System.out.println("Uses it's limbs"); 

    } 

    @Override 
    public void sleep() { 
     System.out.println("Sleeps on it's tummy"); 

    } 

} 


public class Snake extends Reptile{ 

    @Override 
    public void move() { 
     System.out.println("Crawls"); 

    } 

    @Override 
    public void sleep() { 
     System.out.println(""); 

    } 

} 

Wie Sie in diesem Beispiel beobachten, Dog erstreckt Mammal und SnakeReptile erstreckt. Daher zu einem bestimmten Zeitpunkt, Dogwird immer ein Mammal und ein Snakeimmer sein ein Reptile. Daher ist diese ist eine Beziehung baut eine starke Bindung zwischen zwei Einheiten. Während der Ausführung, solange DogMammal erstreckt, kann es kein Reptile oder etwas anderes sein.

Während zurück zu kommen hat-eine Beziehung (Zusammensetzung), kann ich sagen, dass ein Personhat-aCar. Ich gebe nicht den Typ der Car dieser Person an. Lass uns zur OO-Perspektive zurückkehren, um das besser zu verstehen.

Betrachten Sie diese Person Klasse

public class Person { 
    private String name; 
    private String address; 

    private Car car; 

    public Person(String name, String address, Car car) { 
     super(); 
     this.name = name; 
     this.address = address; 
     this.car = car; 
    } 


} 

Es hier gesehen werden kann, dass ein Person hat-ein Name, Anschrift und Auto. Der Code für Auto und verwandte Klassen geht unter:

public class Car { 
    //Car related methods 
} 

public class Ferrari extends Car{ 
    //Ferrari specific methods, attributes 
} 

public class Bmw extends Car{ 
    //BMW specific attributes, methods. 
} 

Es ist ersichtlich, dass BMW und Ferrari sind Arten von Car. Jetzt zurück zu der Aussage "Person hat-ein Auto", das Auto könnte jedes Auto sein. Es könnte ein Ferrari oder BMW oder irgendetwas anderes sein. Dies kann bei der Erstellung von Person Objekt übergeben werden.

Person john = new Person("John", "#81, 2nd Street,..", new Ferrari());

Es ist ersichtlich, dass John in einem FerrariCar nimmt. Hier kann John jede Art von Car annehmen, die während der Objekterstellung (dynamische Natur) übergeben wird. Daher wird dieses Maß an Flexibilität durch has-a (Zusammensetzung) Beziehung zur Verfügung gestellt.

Ich hoffe, dass dies Ihre Zweifel löscht.

Verwandte Themen