Nach dieser Lektion kannst du
In der letzten Lektion haben wir zwei Klassen erstellt: Haustier und Hund. Dabei ist dir vielleicht aufgefallen, dass beide Klassen viele Gemeinsamkeiten besitzen. Beide haben beispielsweise einen Besitzer, beide können fressen und schlafen.
Wenn wir diese Informationen in jeder Klasse erneut notieren müssten, würden unsere Klassendiagramme schnell unübersichtlich werden. Außerdem entsteht ein weiteres Problem: Ändert sich später eine Eigenschaft, müsste sie an mehreren Stellen angepasst werden.
Genau dieses Problem löst die Vererbung.
In der objektorientierten Programmierung beschreibt Vererbung eine Ist-eine-Beziehung. Ein Hund ist ein Säugetier. Eine Katze ist ein Säugetier. Ein Säugetier ist ein Tier.
Eine speziellere Klasse übernimmt automatisch alle Attribute und Methoden einer allgemeineren Klasse. Man sagt auch: Die Unterklasse erbt von der Oberklasse. Die Oberklasse stellt gemeinsame Eigenschaften zur Verfügung.
Überlegen wir zunächst, welche Eigenschaften wirklich für jeden Hund gelten und welche eigentlich alle Säugetiere besitzen. Ein Säugetier besitzt beispielsweise die Fähigkeiten säugen() und brutpflege(). Diese Eigenschaften gelten nicht nur für Hunde, sondern für viele andere Säugetiere. Deshalb verschieben wir sie in eine neue Oberklasse.
Jetzt besitzt die Klasse Hund nur noch ihre hundespezifischen Eigenschaften. Die Methoden säugen() und brutpflege() werden automatisch von der Oberklasse übernommen. Sie müssen deshalb nicht erneut in der Klasse Hund eingetragen werden. Das macht Klassendiagramme deutlich übersichtlicher.
Alles, was bereits in einer Oberklasse vorhanden ist, wird automatisch an die Unterklasse vererbt.
Jetzt können wir unser Modell erneut verbessern. Nicht nur Säugetiere sind Tiere – auch Vögel, Fische oder Reptilien gehören dazu. Alle Tiere können sich jedoch fortbewegen. Deshalb führen wir eine noch allgemeinere Klasse ein: Tier.
Die Klasse Tier enthält ausschließlich das Verhalten, das wirklich jedes Tier besitzt. Die Klasse Säugetier übernimmt diese Methode automatisch und ergänzt sie um eigene Eigenschaften. Auch Hund erhält schließlich alle Methoden seiner Oberklassen.
Ein Hund besitzt damit automatisch fortbewegen(), saeugen(), brutpflege() und bellt() – obwohl in seiner eigenen Klasse lediglich bellt() eingetragen werden müsste. Dadurch erkennt man sofort, welche Eigenschaften speziell für Hunde sind und welche bereits allgemein definiert wurden.
In einer späteren Lektion werden wir sehen, dass ein Hund einige dieser geerbten Methoden sogar an seine eigenen Bedürfnisse anpassen kann. Dieses Konzept nennt man Polymorphie.
Manchmal reicht eine einzige Oberklasse nicht aus. Eine Klasse kann in manchen Programmiersprachen auch Eigenschaften von mehreren Oberklassen gleichzeitig übernehmen. Dieses Konzept nennt man Mehrfachvererbung.
Der Hund würde nun Eigenschaften aus beiden Oberklassen übernehmen – Besitzer von Haustier, saeugen() und brutpflege() von Säugetier. Die Klasse Hund müsste diese Eigenschaften nicht selbst definieren.
Nicht jede Programmiersprache unterstützt Mehrfachvererbung. Python erlaubt sie beispielsweise, Java dagegen nicht. Das UML-Klassendiagramm kann Mehrfachvererbung jedoch unabhängig von der späteren Programmiersprache darstellen.
Der wohl häufigste Fehler betrifft die Richtung des Vererbungspfeils. Viele zeichnen den Pfeil von der Oberklasse zur Unterklasse. Das ist falsch – der Pfeil zeigt immer auf die Oberklasse.
Man kann sich merken: Der Pfeil zeigt immer dorthin, woher geerbt wird.
Für eine normale Vererbung wird in UML immer dieselbe Darstellung verwendet: eine durchgezogene Linie und ein weißer, nicht ausgefüllter Dreieckspfeil – genau wie in den Diagrammen dieser Lektion. Andere Linien oder ausgefüllte Pfeilspitzen bedeuten in UML etwas völlig anderes.
Dieser Fehler passiert besonders häufig. Viele denken intuitiv: „Der Admin ist wichtiger als der User, also muss der Admin oben stehen.“ Genau das ist jedoch falsch.
Betrachten wir ein Benutzerverwaltungssystem. Jeder neue Benutzer erhält zunächst die Rolle User. Ein Administrator kann alles, was ein User kann – und zusätzlich noch weitere Aufgaben übernehmen.
Der Admin erbt vom User. Er übernimmt alle Eigenschaften und Berechtigungen des Users und erweitert diese um zusätzliche Funktionen. Deshalb nennt man die Oberklasse auch Basisklasse. Sie enthält die gemeinsamen Eigenschaften. Die Unterklasse baut darauf auf und ergänzt weitere Merkmale.
In der nächsten Lektion lernen wir mit der Kapselung, warum Attribute in UML meist als private gekennzeichnet werden und wie Klassen ihre Daten vor unerlaubten Zugriffen schützen.