OOP Vererbung: Grundlagen, Inheritance & Polymorphie
Dieser Beitrag ist eine Begriffserklärung zur Vererbung in der objektorientierten Programmierung – inklusive Prüfungsfragen und Tags.
In a Nutshell
Vererbung erlaubt es, gemeinsame Eigenschaften und Verhalten in einer Basisklasse zu definieren und in Unterklassen wiederzuverwenden. Ziel ist Wiederverwendung, Polymorphie und klare Typbeziehungen, ohne redundanten Code.
Kompakte Fachbeschreibung
Vererbung bildet eine ist-ein-Beziehung zwischen Typen, bei der eine Unterklasse alle öffentlich, geschützten Merkmale der Basisklasse erbt und erweitern oder überschreiben kann.
Sie ermöglicht Polymorphie, dynamische Bindung und späte Methodenauswahl. Dispatch erfolgt über den tatsächlichen Objekttyp zur Laufzeit.
Man unterscheidet Implementierungsvererbung von Schnittstellenvererbung, etwa via Interfaces. Das Liskov Substitution Principle fordert, dass Unterklassen sich wie ihre Basisklasse verhalten, ohne Klienten zu überraschen.
Probleme wie fragile Basisklasse, Diamond Problem, enge Kopplung sprechen für Komposition vor Vererbung, wenn nur Wiederverwendung ohne echte ist-ein-Beziehung benötigt wird.
Prüfungsrelevante Stichpunkte
- Ist-ein-Beziehung zwischen Unterklasse und Basisklasse
- Polymorphie ermöglicht dynamische Methodenaufrufe zur Laufzeit
- Liskov Substitution Principle: Unterklassen müssen durch Basisklassen ersetzbar sein
- Diamond Problem: Mehrfachvererbung kann zu Ambiguitäten führen
- Implementierungsvererbung vs Schnittstellenvererbung
- UML-Darstellung: Offene Pfeilspitze von Subklasse zur Superklasse
- Zugriffsmodifizierer steuern Erweiterbarkeit und Überschreibbarkeit
- Komposition vor Vererbung bei reiner Wiederverwendung
Kernkomponenten
- Basisklasse (Superklasse): Gemeinsame Eigenschaften und Verhalten
- Unterklasse (Subklasse): Erbt und erweitert Basisklasse
- Methodenüberschreibung: Angepasstes Verhalten in Unterklassen
- Polymorphie: Ein Interface, viele Implementierungen
- Dynamische Bindung: Methodenaufruf zur Laufzeit aufgelöst
- Abstrakte Klassen: Können nicht instanziiert werden
- Interfaces: Reine Vertragsdefinition ohne Implementierung
- Final-Methoden: Können nicht überschrieben werden
Praxisbeispiel
// Beispiel: Vererbung in der Tierhierarchie
abstract class Tier {
protected String name;
public Tier(String name) {
this.name = name;
}
public abstract void machGeraeusch();
public void schlafen() {
System.out.println(name + " schläft.");
}
}
class Hund extends Tier {
public Hund(String name) {
super(name);
}
@Override
public void machGeraeusch() {
System.out.println(name + " bellt: Wuff!");
}
public void wedleSchwanz() {
System.out.println(name + " wedelt mit dem Schwanz.");
}
}
class Katze extends Tier {
public Katze(String name) {
super(name);
}
@Override
public void machGeraeusch() {
System.out.println(name + " miaut: Miau!");
}
}
// Polymorphie in Aktion
Tier[] tiere = {new Hund("Bello"), new Katze("Mimi")};
for (Tier tier : tiere) {
tier.machGeraeusch(); // Dynamische Bindung
tier.schlafen();
}
Vorteile und Nachteile
Vorteile
- Code-Wiederverwendung: Gemeinsames Verhalten zentral definieren
- Polymorphie: Einheitliche Behandlung verschiedener Typen
- Erweiterbarkeit: Neue Funktionalität durch Unterklassen hinzufügen
- Strukturierung: Klare Hierarchien und Beziehungen
Nachteile
- Enge Kopplung: Unterklassen eng an Basisklassen gebunden
- Fragile Basisklasse: Änderungen können alle Unterklassen brechen
- Diamond Problem: Mehrfachvererbung kann zu Konflikten führen
- Over-Engineering: Vererbung wo Komposition besser wäre
Häufige Prüfungsfragen
-
Was ist der Unterschied zwischen Vererbung und Komposition? Vererbung ist eine ist-ein-Beziehung, Komposition eine hat-ein-Beziehung. Komposition bevorzugen bei reiner Wiederverwendung.
-
Erklären Sie das Liskov Substitution Principle! Unterklassen müssen durch ihre Basisklassen ersetzbar sein, ohne dass das Programmverhalten sich ändert.
-
Was ist das Diamond Problem? Bei Mehrfachvererbung kann eine Klasse von zwei Basisklassen erben, die wiederum von einer gemeinsamen Basisklasse erben.
-
Wann sollte man abstrakte Klassen vs Interfaces verwenden? Abstrakte Klassen für gemeinsame Implementierung, Interfaces für reine Vertragsdefinition.
Wichtigste Quellen
- https://de.wikipedia.org/wiki/Vererbung_(Programmierung)
- https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
- https://refactoring.guru/de/design-patterns