# Komposition an Stelle von Vererbung



## looparda (14. Dez 2018)

Ich habe Probleme mit dem Satz


> Moreover, because an object's implementation will be written in terms of object interfaces, there are substantially fewer implementation dependencies.


 aus dem Buch Design Patterns Elements of Reusable Object-Oriented Software von von Erich Gamma, Richard Helm et al.
Mir ist nicht klar, was mit object interfaces gemeint ist und die Folgerung, dass weniger Implementierungsabhängigkeiten vorhanden sind. Kann das jemand erklären?


----------



## mihe7 (14. Dez 2018)

Naja, jedes Objekt besitzt Methoden, die zur Kommunikation mit dem Objekt gedacht sind. Die Gesamtheit dieser Methoden bilden die Objekt-Schnittstelle. Jede Methode definiert einen Vertrag im Sinne von Parametern, Rückgaben sowie Vor- und Nachbedingungen. Man kann diese Schnittstelle in Java z. B. auch separat als "interface" definieren.

Da es bei einem solchen Vertrag zwei Seiten (Anbieter und Nutzer) gibt, hat dies entsprechende Auswirkungen: der Anbieter muss seine Implementierung danach ausrichten, dass der Vertrag eingehalten wird. Der Nutzer kann sich dagegen auf die Einhaltung des Vertrags verlassen und hängt damit nicht mehr (unmittelbar) von der Implementierung ab.


----------



## looparda (14. Dez 2018)

Aber bei Vererbung habe ich doch auch die Schnittstelle. Durch LSP ist Einhaltung der Vorbedinungen und Nachbedingungen für die Subtypen ebenfalls beschrieben. Mir wird nicht klar warum sich das durch die Komposition an Stelle von Vererbung ergibt.


----------



## mihe7 (14. Dez 2018)

looparda hat gesagt.:


> Mir wird nicht klar warum sich das durch die Komposition an Stelle von Vererbung ergibt.


Das hat ja auch niemand behauptet. 

Bei Vererbung ist die erbende Klasse automatisch an die Implementierung der Elternklasse gebunden. Bei Komposition dagegen nicht.


----------



## mrBrown (14. Dez 2018)

Bei Komposition programmierst du gegen die Schnittstelle, bei Vererbung aber gegen den konkreten Typ (die Superklasse) und deren Implementierung.

Bei Komposition besteht das eigene Interface nur aus dem, was man selbst preis gibt, bei Vererbung aus dem eigenen und dem des Supertypes.


Ein passendes Bespiel ist das häufige "Map so erweitern, dass die Anzahl der hinzugefügten Elemente gezählt wird":

In der naiven "extends HashMap"-Implementation muss man die Internat von HashMap kennen, um die Methoden passend überschreiben zu können (muss nur add überschrieben werden, oder auch addAll? oder werden dann Dinge doppelt gezählt? Wie sieht das ganze beim Konstruktor aus?). Zusätzlich ist dann die zählende Map immer eine HashMap, die Implementierung kann also nie geändert werden.

In der Kompositions-Variante implementierst du das Map-Interface und delegierst alles an eine interne Map-Instanz.
Durch das delegieren musst du keinerlei Details der genutzten Map kennen, nach außen gibst du nur das Map-Interface preis und kannst so auch die genutzte Map-Implementierung ändern.


----------



## looparda (14. Dez 2018)

mihe7 hat gesagt.:


> Das hat ja auch niemand behauptet.


In meinen Unterlagen der Uni wird das als Vorteil von Komposition an Stelle von Vererbung aufgelistet. Habe versucht es anhand der Quelle nachzuvollziehen.




mihe7 hat gesagt.:


> Bei Vererbung ist die erbende Klasse automatisch an die Implementierung der Elternklasse gebunden. Bei Komposition dagegen nicht.


Das ist eigentlich offensichtlich und macht den Unterschied jetzt klar. Danke!

Danke für das Beispiel @mrBrown


----------

