10.1 Eine Unterklasse erweitert eine Oberklasse

Aufgabe

Aufgabe 10-1: robi.drehUm()

Soll sich der Roboter in einem Szenario umdrehen, müssen wir bisher zweimal seine Methode drehLinks() beziehungsweise drehRechts() aufrufen. Eine Methode drehUm() bietet die Klasse Roboter leider nicht an. Das möchten wir nun ändern.

Die Idee liegt nahe, dazu den Quellcode der Klasse Roboter um die neue Methode drehUm() zu erweitern. Es gibt jedoch einige Argumente, die dagegen sprechen, eine Klasse, die von Dritten programmiert wurde, zu verändern:

  • Es kann sein, dass uns lediglich der Bytecode der Klasse vorliegt und wir keinen Zugriff auf den Quellcode der Klasse haben.
  • Haben wir Zugriff auf den Quellcode und ändern wir diesen ab, dann müssen wir unsere Anpassungen erneut vornehmen, sobald der Entwickler der Klasse eine neue Version zur Verfügung stellt.
  • Je nach Komplexität ist es unter Umständen recht zeitaufwendig, zunächst die bisherige Funktionsweise der beteiligten Methoden zu anaylisieren. Bisher war ein solches Verständnis nicht notwendig, da wir lediglich wissen mussten, was die Methode bewirkt, nicht wie sie dies erreicht.

Wir möchten also die Fähigkeiten der Klasse Roboter erweitern, dabei den Quellcode der Klasse Roboter jedoch nicht verändern. Genau dies ermöglicht uns das Konzept der Vererbung.

Aus einer bestehenden Klasse (= Oberklasse) können neue Klassen (= Unterklasse bzw. abgeleitete Klasse) abgeleitet werden. Die Unterklasse erbt dabei alle Attribute und Methoden der Oberklasse und kann darüber hinaus um neue Attribute und Methoden erweitert werden.

Die Vererbung wird im UML-Klassendiagramm durch einen Pfeil, bestehend aus einer durchgezogenen Linie mit einem nicht ausgefüllten Dreieck als Pfeilspitze, dargestellt, der von der Unter- zur Oberklasse zeigt.

Allgemein
img/Abb_10_1a_UML_Vererbung_Oberklasse.svg
Beispiel
img/Abb_10_1b_UML_Vererbung_Roboter.svg
Abb. 10-1: Vererbung im UML-Klassendiagramm

Bei der Deklaration einer neuen Klasse bewirkt das Schlüsselwort extends, dass diese Klasse eine Unterklasse der nachfolgend genannten Klasse wird. Sie erbt damit alle Attribute und Methoden ihrer Oberklasse.

JAVA
public class Unterklasse extends Oberklasse {
    // Attribute und Methoden der Unterklasse ...
}
JAVA
public class RoboterErweitert extends Roboter {
    // Attribute und Methoden der Klasse RoboterErweitert ...
}
Abb. 10-2: Vererbung in JAVA
Merke: Vererbung
Aufgabe

Aufgabe 10-1: robi.drehUm() (Fortsetzung)

  1. Erstellen Sie den Quellcode der Klasse RoboterErweitert, einer Unterklasse der Klasse Roboter.

    Zusätzlich zu den von ihrer Oberklasse geerbten Methoden soll die Klasse RoboterErweitert über die öffentliche Methode drehUm() verfügen. Innerhalb des Methodenrumpfes von drehUm() soll entweder zweimal die Methode drehLinks() oder zweimal die Methode drehRechts() aufgerufen werden. Da die neue Klasse diese geerbt hat, kann sie diese aufrufen, auch wenn diese nicht in ihr selbst deklariert sind.

    Lösung
    Lösung
    JAVA
    public class RoboterErweitert extends Roboter {

         public void drehUm() {
            this.drehLinks();
            this.drehLinks();
         }


    }
    Abb. 10-3: Die Klasse RoboterErweitert
  2. Passen Sie die Klasse Szenario anschließend so an, dass robi nun ein Objekt der Klasse RoboterErweitert ist. Testen Sie dann die neue Methode, indem Sie sie in der Methode steuereRobi() aufrufen. Erstellen Sie zum Abschluss ein kleines Spielbrett und starten Sie die Simulation.

    Lösung
    Lösung
    JAVA
    public class Szenario {

        private RoboterErweitert robi;
        
        public void erstelleRobi(Spielbrett pSpielbrett){
            robi = new RoboterErweitert();
            robi.setSpielbrett(pSpielbrett);
            robi.starteAufFeld(1,1);
        }
            
        public void steuereRobi() {
            robi.drehUm();
        }

    }
    Abb. 10-4: Anpassung der Klasse Szenario

Generalisierung und Spezialisierung

Die Möglichkeit bereits existierende Klassen in neuen Softwareprojekten wiederverwenden zu können, ohne dabei detaillierte Kenntnisse über deren Codierung besitzen zu müssen, ist ein großer Vorteil objektorientierter Programmiersprachen.

Eine Klasse, die sehr speziell auf ein bestimmtes Problem zugeschnitten ist, ist in anderen Situationen aufgrund ihrer Spezialisierung häufig ungeeignet. Je allgemeiner eine Klasse gehalten ist, desto vielseitiger lässt sie sich in verschiedenen Situationen wiederverwenden. Natürlich wird sie dabei aufgrund ihrer Allgemeingültigkeit nicht immer alle Anforderungen einer bestimmten Situation exakt erfüllen können. Aber sie kann als Oberklasse dienen, aus der Unterklassen abgeleitet werden, die speziell an die jeweiligen Anforderungen angepasst sind.

Je nachdem aus welcher Richtung man die Vererbung betrachtet, lässt sich die Beziehung zwischen Oberklasse und Unterklasse als Generalisierung oder Spezialisierung bezeichnen.

Aufgabe

Aufgabe 10-2: Raumverwaltung

In einer Schulverwaltungssoftware sollen auch alle Räume einer Schule verwaltet werden können.

Jedem Raum soll eine eindeutige Nummer (zum Beispiel: A10) und das entsprechende Geschoss (zum Beispiel: 1. OG) zugewiesen werden können. Zusätzlich soll es möglich sein die Grundfläche des Raumes zu erfassen (zum Beispiel: 50,5 qm).

Bei Unterrichtsräumen wird außerdem die Anzahl der Sitzplätze benötigt. Des Weiteren soll angegeben werden, ob in dem Unterrichtsraum ein PC, ein Beamer bzw. ein interaktives Whiteboard vorhanden sind.

Für Computerräume soll darüber hinaus die Anzahl der Computerarbeitsplätze angegeben werden.

Aufgabe

Entwickeln Sie ein geeignetes UML-Klassendiagramm. Lösung

Lösung
img/Abb_10_5_UML_Raumverwaltung.svg
Abb. 10-5: Raumverwaltung (UML-Klassendiagramm)