Nach dieser Lektion kannst du
In der vorherigen Lektion haben wir die Klasse Hund kennengelernt. Natürlich ist ein Hund aber nicht einfach irgendein Lebewesen – er gehört zur Gruppe der Säugetiere. Diese Beziehung möchten wir ebenfalls in unserem Klassendiagramm darstellen. Dafür verwenden wir eine abstrakte Klasse.
Stell dir vor, du gehst durch einen Zoo. Vor jedem Gehege steht ein Schild. Dort liest du beispielsweise 🦒 Giraffe, 🐘 Elefant, 🦓 Zebra oder 🫏 Esel.
Du wirst jedoch vermutlich niemals ein Schild entdecken, auf dem steht: „Säugetier“. Warum? Weil Säugetier keine konkrete Tierart, sondern lediglich eine wissenschaftliche Kategorie ist. Im Gehege lebt immer ein konkretes Tier – es gibt also einen Elefanten, eine Giraffe, einen Hund, aber kein „Säugetier“ als eigenständiges Tier.
Ganz genauso verhält es sich bei abstrakten Klassen. Eine abstrakte Klasse beschreibt gemeinsame Eigenschaften und Methoden mehrerer Klassen. Sie dient als gemeinsamer Bauplan. Aus ihr werden jedoch keine Objekte erzeugt.
Man erzeugt beispielsweise einen Hund, eine Katze oder einen Elefanten – aber niemals direkt ein Objekt der Klasse Säugetier. Deshalb wird eine abstrakte Klasse in UML kursiv dargestellt oder mit der Eigenschaft {abstract} gekennzeichnet.
Der Hund übernimmt alle Eigenschaften und Methoden seines Säugetiers. Man sagt: Die Klasse Hund erbt von der abstrakten Klasse Säugetier.
Ohne eine abstrakte Klasse müsste jede einzelne Tierklasse dieselben Eigenschaften erneut definieren – zum Beispiel Alter, Gewicht und Atmen. Diese Informationen existieren jedoch bereits im Säugetier. Dadurch vermeiden wir doppelte Modellierung.
Neben abstrakten Klassen gibt es noch ein weiteres wichtiges Konzept: Schnittstellen (Interfaces). Auf den ersten Blick sehen sie ähnlich aus, sie verfolgen jedoch einen anderen Zweck.
Die abstrakte Klasse Säugetier beschreibt eine gemeinsame Tierart. Sie besitzt deshalb Eigenschaften wie Alter und Gewicht, und Methoden wie atmen() und schlafen(). Sie beschreibt also weiterhin ein Objekt – nur eben kein Objekt, das direkt erzeugt werden darf.
Eine Schnittstelle beschreibt dagegen keine Art von Objekt. Sie beschreibt lediglich ein bestimmtes Verhalten. Nehmen wir die Schnittstelle <<interface>> Beweglich. Sie sagt lediglich: „Alles, was beweglich ist, muss sich bewegen können.“ Sie interessiert sich überhaupt nicht dafür, ob es ein Hund ist, ein Auto, ein Roboter oder eine Drohne. Alle können beweglich sein.
Eine Schnittstelle ist daher eher ein Sammelbehälter für gemeinsame Verhaltensweisen. Sie besitzt deshalb keine Attribute.
Die Schnittstelle legt lediglich fest: Jede Klasse, die beweglich ist, muss eine Methode sichBewegen() besitzen. Wie diese Bewegung später aussieht, entscheidet jede Klasse selbst – ein Hund läuft, ein Vogel fliegt, ein Fisch schwimmt.
Eine Klasse kann eine Schnittstelle übernehmen. Technisch ähnelt dies einer Vererbung. In UML wird dafür jedoch eine andere Beziehung verwendet: Statt einer durchgezogenen Linie wird eine gestrichelte Linie verwendet. Außerdem spricht man nicht von Vererbung, sondern von einer Realisierung.
Man sagt: Die abstrakte Klasse Säugetier realisiert die Schnittstelle Beweglich. Und anschließend: Die Klasse Hund erbt von Säugetier.
Eine Vererbung bedeutet: „Ich bin eine speziellere Form davon.“ Ein Hund ist tatsächlich ein Säugetier. Eine Schnittstelle bedeutet dagegen: „Ich erfülle dieses Verhalten.“
Deshalb spricht man hier von einer Realisierung.
Eine Schnittstelle besitzt niemals Attribute – nur Methodensignaturen. Wird einer Schnittstelle versehentlich ein Attribut zugewiesen, handelt es sich in UML eigentlich um eine abstrakte Klasse, nicht mehr um ein Interface.
| Abstrakte Klasse | Schnittstelle |
|---|---|
| Beschreibt eine gemeinsame Objektart. | Beschreibt ausschließlich gemeinsames Verhalten. |
| Darf Attribute besitzen. | Besitzt keine Attribute. |
| Darf Methoden mit Implementierung enthalten. | Enthält normalerweise nur Methodensignaturen. |
| Von ihr wird geerbt. | Sie wird realisiert. |
| Durchgezogene Linie. | Gestrichelte Linie. |
Eine abstrakte Klasse beschreibt einen gemeinsamen Bauplan mehrerer Klassen und darf selbst nicht instanziiert werden. Eine Schnittstelle beschreibt dagegen ausschließlich gemeinsames Verhalten und enthält deshalb keine Attribute. Klassen erben von abstrakten Klassen, Schnittstellen werden realisiert.
Abstrakte Klassen und Schnittstellen dienen beide dazu, Gemeinsamkeiten zwischen Klassen zu beschreiben. Der entscheidende Unterschied liegt jedoch in ihrer Aufgabe: Eine abstrakte Klasse beschreibt eine gemeinsame Objektart und kann Eigenschaften sowie Methoden enthalten. Eine Schnittstelle beschreibt dagegen ausschließlich gemeinsames Verhalten und definiert, welche Methoden eine Klasse bereitstellen muss. Dadurch entstehen gut strukturierte Klassendiagramme, die auch bei großen Softwaresystemen übersichtlich und leicht erweiterbar bleiben.