Informatik

Vererbung in Java: Klassen sinnvoll erweitern

Vererbung in Java: Klassen sinnvoll erweitern
Vererbung in Java: Klassen sinnvoll erweitern
Für Quiz, Lückentext, Lernkarten und Fortschritt ist JavaScript nötig. Alle Inhalte und Lösungen bleiben direkt lesbar.

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.

Deine Lernziele

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.

Definition

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:

  • Produkt ist die Oberklasse.
  • Buch ist 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:

  1. übernehmen: Eine geerbte Methode unverändert verwenden,
  2. ergänzen: neue Attribute oder Methoden hinzufügen,
  3. ü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.

Merke

Frage zuerst: „Ist jedes Objekt der Unterklasse auch sinnvoll als Objekt der Oberklasse verwendbar?“ Ein gemeinsames Merkmal allein reicht für Vererbung nicht aus.

Teste dich
Frage 1 von 2LeichtWelche Aussage beschreibt eine passende Vererbung?
Lösung: Ein Buch ist eine besondere Art von Produkt. — Eine Unterklasse muss eine besondere Art der Oberklasse sein. Bestandteile und Eigenschaften werden gewöhnlich nicht als Oberklassen modelliert.
Frage 2 von 2MittelSparkonto erbt von Konto. Was kann Sparkonto sinnvoll tun?
Lösung: Allgemeine Kontofunktionen übernehmen und eine Zinsfunktion ergänzen. — Eine Unterklasse kann Verhalten übernehmen, ergänzen und überschreiben. Konstruktoren selbst werden in Java nicht vererbt.
Wie wird eine Unterklasse in Java geschrieben?

Java verwendet das Schlüsselwort extends. Die Grundform lautet: class Unterklasse extends Oberklasse { ... }.

Beispiel

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.

Lückentext

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.

Lösungen: Lücke 1: extends; Lücke 2: private; Lücke 3: überschreiben. 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.

Definition

Polymorphie

Polymorphie bedeutet hier: Eine Variable des Oberklassentyps kann auf Objekte verschiedener Unterklassen verweisen. Beim Methodenaufruf wird die Implementierung des konkreten Objekts ausgeführt.

Beispiel

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 aus Rectangle aus.
  • s2.draw(); führt die Implementierung aus Circle aus.

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.

Teste dich
Frage 1 von 3LeichtWelche Annotation kennzeichnet in Java eine überschriebene Methode?
Lösung: @Override@Override hilft, Tippfehler und unpassende Methodensignaturen beim Überschreiben zu erkennen.
Frage 2 von 3MittelShape form = new Circle(); wird ausgeführt. Circle überschreibt draw(). Welche Methode läuft bei form.draw()?
Lösung: Die draw()-Implementierung aus Circle. — Bei dynamischer Methodenbindung wird die zum konkreten Objekt passende überschriebene Methode aufgerufen.
Frage 3 von 3SchwerWarum muss eine Unterklasse das erwartete Verhalten der Oberklasse bewahren?
Lösung: Damit sie überall eingesetzt werden kann, wo die Oberklasse erwartet wird. — Eine echte Subtypbeziehung verlangt mehr als ähnliche Struktur: Verwender der Oberklasse dürfen durch das Verhalten der Unterklasse nicht unerwartet scheitern.
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.

Beispiel

GameObject besitzt den Konstruktor GameObject(String typ). Level erbt von GameObject und ergänzt die Zahl stufe.

Der Konstruktor von Level folgt diesem Ablauf:

  1. Level(String typ, int stufe) wird aufgerufen.
  2. super(typ) initialisiert zuerst den GameObject-Teil.
  3. 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.

Teste dich
Frage 1 von 1MittelDie Oberklasse besitzt nur Produkt(int nummer). Was muss der Unterklassenkonstruktor tun?
Lösung: Als ersten Konstruktoraufruf einen passenden Aufruf wie super(nummer) ausführen. — Ein expliziter passender Oberklassenkonstruktor ist nötig, wenn super() nicht verfügbar ist. Der Konstruktoraufruf steht zuerst.
Wann ist Vererbung eine gute Modellierung?

Eine sprachlich plausible Einteilung ist noch keine gute Klassenhierarchie. Prüfe zwei Bedingungen:

  1. Ist-ein-Test: Ist die Unterklasse wirklich eine besondere Art der Oberklasse?
  2. Austauschbarkeit: Verhält sich jedes Unterklassenobjekt so, wie Verwender der Oberklasse es erwarten?
Definition

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.

Gut zu wissen

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.

Beispiel

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.

Teste dich
Frage 1 von 3LeichtWelche Beziehung spricht für Komposition statt Vererbung?
Lösung: Ein Auto hat einen Motor. — „Hat ein“ beschreibt einen Bestandteil oder eine Zusammenarbeit. Dafür ist Komposition meist geeigneter.
Frage 2 von 3MittelEine Unterklasse besitzt ähnliche Attribute wie die Oberklasse, verletzt aber deren Verhaltensregeln. Was folgt daraus?
Lösung: Die Vererbungsbeziehung ist trotz der Ähnlichkeit ungeeignet. — Strukturähnlichkeit reicht nicht. Ein Unterklassenobjekt darf Verwender des Oberklassentyps nicht durch unvereinbares Verhalten überraschen.
Frage 3 von 3SchwerEine Person kann gleichzeitig Kunde und Mitarbeiter sein. Welche Modellierung ist am flexibelsten?
Lösung: Die Person wird mit getrennten Rollenobjekten verknüpft. — Mehrere oder wechselnde Rollen werden besser als Beziehungen modelliert als durch eine starre Vererbungshierarchie.
Karteikasten
Karteikasten

Überlege zuerst selbst und drehe die Karte anschließend zum Prüfen um.

Alles auf einen Blick
Mindmap
  • 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
Abschluss-Check
Teste dich
Frage 1 von 5LeichtWelche Formulierung trifft Vererbung am besten?
Lösung: Eine speziellere Klasse übernimmt und verändert bei Bedarf Merkmale einer allgemeineren Klasse. — Vererbung verbindet Ober- und Unterklasse dauerhaft und drückt eine fachlich passende Unterart aus.
Frage 2 von 5MittelWas geschieht bei Oberklasse x = new Unterklasse(); x.methode();, wenn die Unterklasse methode() korrekt überschreibt?
Lösung: Die überschriebene Implementierung der konkreten Unterklasse wird ausgeführt. — Das konkrete Objekt bestimmt bei einer überschriebenen Instanzmethode die ausgeführte Implementierung.
Frage 3 von 5MittelWarum kann ein Unterklassenkonstruktor super(argument) benötigen?
Lösung: Weil der Oberklassenteil mit einem passenden Oberklassenkonstruktor initialisiert werden muss. — Besitzt die Oberklasse keinen erreichbaren parameterlosen Konstruktor, muss die Unterklasse einen passenden Konstruktor ausdrücklich aufrufen.
Frage 4 von 5SchwerEin Team möchte Drucker extends Tinte modellieren, weil ein Drucker Tinte verwendet. Wie sollte es den Entwurf verbessern?
Lösung: Der Drucker sollte ein Tintenobjekt enthalten oder verwenden. — Ein Drucker hat Tinte, ist aber keine Tinte. Diese Beziehung wird durch Komposition dargestellt.
Frage 5 von 5SchwerWelche Prüfung ist vor dem Ergänzen einer neuen Unterklasse am wichtigsten?
Lösung: Ob ihre Objekte überall dort erwartungsgemäß funktionieren, wo die Oberklasse verlangt wird. — Eine Unterklasse ist nur dann ein tragfähiger Subtyp, wenn sie nicht nur ähnlich aufgebaut, sondern auch verhaltensmäßig austauschbar ist.

Passend dazu