Abstrakte Klassen

Mit dem Laden des Videos akzeptierst du die Datenschutzerklärung von YouTube. Wenn du die Menge an Daten reduzieren möchtest, die YouTube von dir sammelt, solltest du dich vorher aus deinem YouTube-Account ausloggen, das Speichern von Cookies für das Google-Ads-Programm deaktivieren und/oder Cookies im Browser blockieren.
YouTube immer automatisch ladenInhaltsverzeichnis
Als Text lesen
Schau dir die folgende Klassenhierarchie an:
Die Methode makeSound()
wird nun in den beiden Unterklassen überschrieben, sodass jede Creature
einen passenden Ton erzeugt. (Das könnte z.B. das Abspielen einer Sound-Datei in einem Computerspiel sein.) Welches Geräusch macht dann aber die Kreatur Creature
selbst?
Diese Frage erscheint dämlich. Creature
ist ja nur ein Oberbegriff für die beiden konkreten Unterklassen Alien
und Sheep
. Wir sollten in der Oberklasse eigentlich gar nicht gezwungen sein, eine spezielle Implementierung für diese Methode anzugeben. Wie lösen wir das Problem?
Abstrakte Klassen
Eine abstrakte Klasse ist eine Klasse, die selbst nicht instanziiert werden kann. Man kann also nicht über den Konstruktor ein neues Objekt dieser Klasse erzeugen.
-
Abstrakte Klassen werden mit dem
abstract
Keyword gekennzeichnet:public abstract class Creature {// ...} - Eine abstrakte Klasse kann trotzdem einen Konstruktor haben. Dieser kann jedoch nur über
super()
(bzw.this()
) aufgerufen werden, um beispielsweise Attribute zu setzen. -
Eine abstrakte Klasse kann abstrakte Methoden enthalten, die zwar nur eine Methodensignatur enthalten, aber keinen Methoden-Körper:
public abstract void makeSound(); // Kein Körper in geschweiften Klammern! -
Abstrakte Klassen bzw. Methoden kennzeichnet man in UML durch kursive Schrift, manchmal auch zusätzlich mit <<abstract>>:
Durch verwendung von abstract
Können wir also eine abstrakte Methode makeSound()
in Creature
deklarieren, ohne dabei angeben zu müssen, was bei der Ausführung passiert. Dieser Teil wird erst dadurch erledigt, dass wir die Methode in den Unterklassen überschreiben. Es kann dabei keine Probleme geben, weil durch abstract
sichergestellt wird, dass niemals eine Instanz von Creature
selbst existiert:
Wann brauche ich das?
Du brauchst abstrakte Klassen immer dann, wenn du eine Oberklasse hast, bei der es keinen Sinn ergeben würde, wenn ein Objekt dieser Klasse (und nur dieser Klasse selbst) existieren würde.
Beispielsweise für die Klassen Car
und GolfCar
sollte Car
vermutlich nicht abstract
sein, weil ein Auto selbst ausreichend spezifisch ist um zu existieren. Wir können direkt in der Klasse Car
angeben, wie beispielsweise das Fahrverhalten eines (gewöhnlichen) Autos funktioniert. Für das obige Beispiel mit Creature
und Alien
/ Sheep
erscheint es aber sinnvoll, Creature
als abstract
zu deklarieren, weil die Verhaltensweise einer allgemeinen Kreatur nicht genau genug beschrieben ist. Man müsste erst wissen, um welche Art von Kreatur genau es sich handelt, um bestimmte Methoden zu implementieren.
Du merkst selbst, dass es hier viel Spielraum für Diskussion gibt. Wie du deine Klassen modellierst bleibt letztlich dir überlassen. Am Ende ist am wichtigsten, dass der Code nicht nur funktional, sondern auch verständlich und erweiterbar ist.
Und noch einmal das Beispiel mit den geometrischen Formen (Zum letzten Mal, versprochen!):
Überlege dir, welche der Klassen und welche der Methoden abstract
sein sollten. Ändere deinen Code entsprechend.
Häufige Fehlerquellen
- Überflüssiger Methodenkörper in abstrakter Methode: Entweder deine Methode ist
abstract
, oder deine Methode hat geschweifte Klammern mit einem Methodenkörper. - Klassen abstrakt, die nicht abstrakt sein sollten, oder umgekehrt
- Methoden abstrakt, die nicht abstrakt sein sollten, oder umgekehrt