- 1 Section
- 10 Lessons
- unbegrenzt
- Objektorientierte Programmierung (OOP)10
Vererbung
Vererbung ist die zweite große Säule der OOP. Die Idee: anstatt eine neue Klasse von Grund auf zu bauen, basierst du sie auf einer bestehenden und erweiterst sie. Wenn du in L1 das Beispiel mit dem Sparbuch gesehen hast – das war Vererbung. Ein Sparbuch ist ein Konto – mit zusätzlichen Eigenschaften.
Diese Lektion zeigt dir wie Vererbung syntaktisch funktioniert, was vererbt wird und was nicht, wie du Methoden in Unterklassen überschreibst (Override), wann Vererbung sinnvoll ist und wann nicht (das ist überraschend wichtig!), und das berüchtigte Diamond-Problem bei Mehrfachvererbung.
1) Das Grundprinzip
Vererbung modelliert die „ist-ein"-Beziehung (englisch: is-a). Ein Dackel ist ein Hund. Ein Hund ist ein Säugetier. Ein Säugetier ist ein Tier. Diese Hierarchien gibt's überall in der Realität, und OOP bildet sie 1:1 ab:
2) Syntax in verschiedenen Sprachen
Die Syntax ist in jeder Sprache etwas anders, das Konzept ist gleich:
Beachte das super(): damit ruft die Unterklasse den Konstruktor der Oberklasse auf. In Java muss super(...) die erste Zeile im Unterklassen-Konstruktor sein. In Python ist es Konvention.
3) Was wird vererbt?
Eine wichtige Frage: was bekommt die Unterklasse von der Oberklasse? Die Antwort hängt von der Sichtbarkeit ab (siehe L4):
| Element der Oberklasse | Wird vererbt? |
|---|---|
public-Methoden und -Felder | ✓ ja, voll zugreifbar |
protected-Methoden und -Felder | ✓ ja, in Unterklassen zugreifbar |
private-Methoden und -Felder | (✗) existieren im Objekt, sind aber für die Unterklasse nicht direkt zugreifbar |
| Konstruktoren | ✗ nicht vererbt – Unterklasse muss eigenen schreiben |
| Statische Methoden und Felder | ✓ technisch vererbt, aber Verhalten sprachenabhängig |
Privat heißt: die Daten gehören dem Objekt, aber nur die Klasse die sie definiert hat darf darauf zugreifen. Die Unterklasse muss über öffentliche oder geschützte Methoden gehen.
4) Method Overriding
Eine Unterklasse kann Methoden der Oberklasse überschreiben – das heißt: gleichen Namen, andere Implementierung. Klassisches Beispiel: alle Tiere können „Laut geben", aber jedes Tier macht es anders.
In Java solltest du @Override als Annotation drüber setzen – nicht zwingend, aber sehr empfohlen. Sie hilft dem Compiler zu prüfen, dass du wirklich eine Methode der Oberklasse überschreibst und nicht versehentlich eine neue mit Tippfehler erfindest.
Das Überschreiben ist die Grundlage für Polymorphismus, der eigene Lektion L6 bekommt.
5) super() – auf den Eltern zugreifen
Manchmal willst du die Methode der Oberklasse nicht komplett ersetzen, sondern sie erweitern. Hier kommt super() ins Spiel – damit rufst du explizit die Eltern-Methode auf:
Manager erweitert die Vorstellung um eine zusätzliche Zeile. Ohne super().vorstellen() in Zeile 15 würde der „Ich bin {name}"-Teil verloren gehen. Das nennt sich Methodenerweiterung.
6) Method Resolution Order (MRO)
Was passiert wenn du eine Methode auf einer tief verschachtelten Klasse aufrufst? Python und Java suchen die Methode in einer bestimmten Reihenfolge. Beispiel mit Dackel → Hund → Tier:
Dackel.__mro__ oder Dackel.mro(). In Klausuren wird das gerne abgefragt – „in welcher Reihenfolge wird gesucht?".7) Einfach- vs. Mehrfachvererbung
Manche Sprachen erlauben einer Klasse nur eine Oberklasse (Java, C#, Kotlin), andere lassen mehrere zu (Python, C++):
- Einfachvererbung: eine Klasse hat genau eine direkte Oberklasse. Macht alles einfacher und vorhersehbarer.
- Mehrfachvererbung: eine Klasse kann von mehreren Klassen gleichzeitig erben. Mächtig aber heikel.
8) Das Diamond-Problem
Bei Mehrfachvererbung kann ein klassisches Problem auftreten: das Diamond-Problem (Rauten-Problem). Eine Klasse erbt indirekt zweimal von derselben Basis-Klasse über zwei verschiedene Pfade:
class D(B, C) – B vor C.Java-Lösung: Mehrfachvererbung von Klassen ist VERBOTEN. Stattdessen Interfaces (siehe L7) – diese können mehrfach implementiert werden, aber haben keinen Zustand.
C++-Lösung: virtuelle Vererbung mit
virtual-Keyword. Komplex und fehleranfällig.
9) IS-A vs. HAS-A
Ein wichtiger Modellierungs-Grundsatz: nicht jede Beziehung zwischen Klassen ist Vererbung. Es gibt zwei Hauptbeziehungen die oft verwechselt werden:
Manager IS-A Mitarbeiter
Auto IS-A Fahrzeug
Person HAS-A Adresse
Bestellung HAS-A Kunde
class Auto extends Motor. Falsch! Ein Auto IST kein Motor, es HAT einen. Richtig: class Auto { private Motor motor; }. Das nennt sich Komposition – oft besser als Vererbung. Das Prinzip „Composition over Inheritance" ist in modernen Sprachen tonangebend.10) Wann Vererbung – wann nicht?
Vererbung ist mächtig, aber wird in der Praxis oft überstrapaziert. Hier eine ehrliche Einschätzung:
Vererbung passt wenn:
- Die Unterklasse wirklich ein Typ der Oberklasse ist (Liskov-Prinzip, siehe L9)
- Die Hierarchie stabil und natürlich ist
- Es Methoden gibt die in allen Unterklassen sinnvoll sind
- Du Polymorphismus brauchst (gleichbehandeln verschiedener Subtypen)
Vererbung passt NICHT wenn:
- Die Unterklasse mehrere Methoden der Oberklasse nicht braucht oder anders implementiert
- Du nur Code wiederverwenden willst, aber keine echte Hierarchie modellierst
- Die Beziehung „HAS-A" ist, nicht „IS-A"
- Die Hierarchie absehbar instabil ist (Anforderungen ändern sich oft)
Modernes Mantra: „Composition over Inheritance". Im Zweifel Komposition (HAS-A) statt Vererbung (IS-A) bevorzugen. Vererbung ist eine starke Bindung – Composition ist flexibler und einfacher zu ändern. Mehr dazu in K49 Design Patterns.
Zusammenfassung
Vererbung modelliert die IS-A-Beziehung und ermöglicht Code-Wiederverwendung. Syntax: class B(A) in Python, extends in Java. Unterklassen erben public/protected Elemente, müssen aber eigenen Konstruktor schreiben. super() ruft den Eltern-Konstruktor oder Eltern-Methoden auf. Method Overriding ersetzt geerbte Methoden in der Unterklasse. Method Resolution Order: Suche bottom-up, erste passende Methode gewinnt. Mehrfachvererbung möglich in Python/C++, verboten in Java – wegen Diamond-Problem. Faustregel „Composition over Inheritance": im Zweifel HAS-A statt IS-A. Vererbung ist die Grundlage für Polymorphismus (L6).
