Vererbung in Java: Klassen sinnvoll erweitern
Bei der Vererbung entsteht aus einer allgemeinen Klasse eine speziellere Klasse. Die Unterklasse übernimmt verwendbare Merkmale der Oberklasse, kann neue ergänzen und Methoden passend überschreiben. Sinnvoll ist das nur, wenn wirklich eine Ist-eine-Art-von-Beziehung besteht und Objekte der Unterklasse die Erwartungen an die Oberklasse erfüllen.
Hake ab, was du schon kannst — und komm am Ende hierher zurück!
Was wird bei der Vererbung übernommen?
Stell dir ein Inventarsystem vor. Jedes Produkt besitzt eine Artikelnummer, einen Preis und einen Hersteller. Ein Buch ist eine besondere Art von Produkt und ergänzt Autor und ISBN.
Vererbung
Vererbung ist eine dauerhafte Beziehung zwischen Klassen. Eine Unterklasse wird aus einer allgemeineren Oberklasse abgeleitet. Sie übernimmt deren zugängliches Verhalten und kann die Klasse spezialisieren.
Für das Beispiel gilt:
Produktist die Oberklasse.Buchist die Unterklasse.- Ein Buch ist ein Produkt.
- Ein Buch übernimmt allgemeine Produktmerkmale und ergänzt buchtypische Merkmale.
Eine Unterklasse kann auf drei Arten spezialisiert werden:
- übernehmen: Eine geerbte Methode unverändert verwenden,
- ergänzen: neue Attribute oder Methoden hinzufügen,
- überschreiben: eine geerbte Methode mit passendem Spezialverhalten neu implementieren.
Vererbung wirkt über mehrere Stufen. Wenn Dungeon von Level und Level von GameObject erbt, ist ein Dungeon auch ein GameObject. Eine solche Kette heißt mehrstufige Vererbung.
Frage zuerst: „Ist jedes Objekt der Unterklasse auch sinnvoll als Objekt der Oberklasse verwendbar?“ Ein gemeinsames Merkmal allein reicht für Vererbung nicht aus.
Wie wird eine Unterklasse in Java geschrieben?
Java verwendet das Schlüsselwort extends. Die Grundform lautet: class Unterklasse extends Oberklasse { ... }.
Die Oberklasse Produkt stellt die Methode beschreibung() bereit. Die Unterklasse wird mit class Buch extends Produkt { ... } deklariert. Ein Buch kann die geerbte Methode verwenden und zusätzlich etwa das Attribut isbn sowie eine Methode autorAnzeigen() besitzen.
Gemeinsame Produktlogik bleibt dadurch in Produkt. Nur die buchtypischen Ergänzungen stehen in Buch.
Java erlaubt einer Klasse nur eine direkte Oberklasse. Mehrere gemeinsame Verträge können stattdessen über Interfaces beschrieben werden. Das ist von der Vererbung einer konkreten Klassenimplementierung zu unterscheiden.
Die Sichtbarkeit bestimmt, worauf die Unterklasse direkt zugreifen darf:
public: allgemein zugänglich,protected: in Unterklassen zugänglich; in Java zusätzlich innerhalb desselben Pakets,private: nur direkt innerhalb der Klasse zugänglich, die das Mitglied deklariert hat.
Ein privates Attribut gehört weiterhin zum Oberklassenteil eines Unterklassenobjekts. Die Unterklasse darf aber nicht unmittelbar darauf zugreifen. Dafür stellt die Oberklasse bei Bedarf geeignete Methoden bereit.
Wähle in jeder Lücke die passende Form und prüfe anschließend deine Antworten.
In Java verbindet das Schlüsselwort eine Unterklasse mit ihrer Oberklasse. Ein nur in der deklarierenden Klasse direkt sichtbares Attribut ist . Eine Unterklasse kann eine geerbte Methode , wenn die Methode dies erlaubt.
extends bezeichnet Klassenvererbung. private schützt den direkten Zugriff von außen und aus Unterklassen. Beim Überschreiben erhält eine geerbte Methode eine passende neue Implementierung.extends bezeichnet Klassenvererbung. private schützt den direkten Zugriff von außen und aus Unterklassen. Beim Überschreiben erhält eine geerbte Methode eine passende neue Implementierung.Wie funktionieren Überschreiben und Polymorphie?
Beim Überschreiben besitzt die Unterklasse eine Methode mit passender Signatur wie die Oberklasse, liefert aber ein spezielleres Verhalten. @Override lässt den Java-Compiler prüfen, ob tatsächlich eine geerbte Methode überschrieben wird.
Polymorphie
Polymorphie bedeutet hier: Eine Variable des Oberklassentyps kann auf Objekte verschiedener Unterklassen verweisen. Beim Methodenaufruf wird die Implementierung des konkreten Objekts ausgeführt.
Eine abstrakte Klasse Shape legt die Methode draw() fest. Rectangle und Circle überschreiben sie jeweils.
Shape s1 = new Rectangle();Shape s2 = new Circle();s1.draw();führt die Implementierung ausRectangleaus.s2.draw();führt die Implementierung ausCircleaus.
Der deklarierte Variablentyp ist in beiden Fällen Shape. Das konkrete Objekt entscheidet zur Laufzeit über die ausgeführte überschreibende Methode. Dies nennt man dynamische Methodenbindung.
Über eine Variable des Oberklassentyps sind nur die dort bekannten Mitglieder direkt erreichbar. Unterklassenspezifische Methoden werden dadurch nicht automatisch sichtbar. Ein Upcast von der Unterklasse zur Oberklasse ist dennoch möglich, weil das Unterklassenobjekt als Oberklassenobjekt verwendbar sein soll.
Wie wird der Oberklassenteil konstruiert?
Konstruktoren werden in Java nicht vererbt. Beim Erzeugen eines Unterklassenobjekts muss jedoch auch sein Oberklassenteil initialisiert werden. Dazu ruft der Unterklassenkonstruktor mit super(...) einen passenden Oberklassenkonstruktor auf.
GameObject besitzt den Konstruktor GameObject(String typ). Level erbt von GameObject und ergänzt die Zahl stufe.
Der Konstruktor von Level folgt diesem Ablauf:
Level(String typ, int stufe)wird aufgerufen.super(typ)initialisiert zuerst denGameObject-Teil.- Danach setzt der Unterklassenkonstruktor sein eigenes Attribut
stufe.
Der Aufruf von super(...) muss als Konstruktoraufruf an erster Stelle stehen. Wird kein Aufruf notiert, versucht Java dort automatisch super() einzusetzen. Das funktioniert nur, wenn ein erreichbarer parameterloser Oberklassenkonstruktor vorhanden ist.
Eine überschreibende Methode kann außerdem mit super.methodenname(...) gezielt die Implementierung der unmittelbaren Oberklasse aufrufen. So kann sie allgemeines Verhalten beibehalten und anschließend Spezialverhalten ergänzen.
Wann ist Vererbung eine gute Modellierung?
Eine sprachlich plausible Einteilung ist noch keine gute Klassenhierarchie. Prüfe zwei Bedingungen:
- Ist-ein-Test: Ist die Unterklasse wirklich eine besondere Art der Oberklasse?
- Austauschbarkeit: Verhält sich jedes Unterklassenobjekt so, wie Verwender der Oberklasse es erwarten?
Komposition
Bei der Komposition enthält oder verwendet ein Objekt ein anderes Objekt. Sie modelliert eine Hat-Beziehung, ohne daraus eine Unterart zu machen.
Apfelkuchen ist ein Kuchen, aber kein Apfel. Die Zutaten gehören als Bestandteile zum Kuchen. Eine Vererbung von Apfel wäre deshalb unpassend.
Auch wechselnde Rollen sprechen gegen starre Unterklassen. Eine Person kann gleichzeitig Kunde und Mitarbeiter sein oder ihre Rolle wechseln. Verknüpfte Rollenobjekte bilden das flexibler ab als immer neue Klassen wie KundeUndMitarbeiter.
Das bekannte Modell Quadrat extends Rechteck wirkt zunächst logisch. Es kann aber problematisch werden, sobald ein veränderbares Rechteck Länge und Breite unabhängig setzen lässt. Gleicht ein Quadrat beim Setzen der Länge automatisch auch die Breite an, verhält es sich anders als ein Verwender eines allgemeinen Rechtecks erwartet. Das zeigt: Mathematische Einordnung allein garantiert noch keine sichere Subtypbeziehung im Programm.
Tiefe Hierarchien und unnötiges Überschreiben erhöhen Änderungsrisiken. Ändert sich eine zentrale Oberklasse, können viele Unterklassen betroffen sein. Halte Hierarchien deshalb überschaubar, kapsle interne Daten und beschreibe das erwartete Verhalten von Methoden eindeutig.
Die Klassenfolge Viereck → Rechteck → Quadrat kann gemeinsame Berechnungen übernehmen. Für ein Rechteck mit Länge 10 und Breite 20 ergibt die geerbte Umfangsberechnung 2 · 10 + 2 · 20 = 60; die Fläche beträgt 10 · 20 = 200.
Ein Quadrat mit Seitenlänge 30 hat den Umfang 4 · 30 = 120 und die Fläche 30² = 900. Die Rechnungen zeigen mögliche Wiederverwendung. Ob die Vererbungsbeziehung auch bei veränderbaren Seiten korrekt bleibt, muss zusätzlich am erwarteten Verhalten geprüft werden.
Karteikasten
Überlege zuerst selbst und drehe die Karte anschließend zum Prüfen um.
Alles auf einen Blick
- Vererbung
- Beziehung
- Oberklasse und Unterklasse
- Ist-eine-Art-von
- Austauschbarkeit
- Java
- `extends`
- `super(...)`
- `@Override`
- Spezialisierung
- übernehmen
- ergänzen
- überschreiben
- Laufzeit
- Polymorphie
- dynamische Methodenbindung
- Entwurfsprüfung
- Verhalten bewahren
- Komposition bei Hat-Beziehungen
- Hierarchien überschaubar halten
- Beziehung
Mit Google fortfahren