Lektion 3 von 7

Klassendiagramm I: Klassen und Beziehungen

Das Klassendiagramm ist der häufigste UML-Typ in der Prüfung. Hier lernst du, eine Klasse vollständig aufzuschreiben, Beziehungen mit Multiplizitäten zu versehen und ein Diagramm aus einem Szenariotext abzuleiten.

  • Etwa 30 Minuten
  • 2 Zeichenaufgaben, 5 Quizfragen
  • Papier und Stift genügen

Aufbau einer Klasse

Eine Klasse (class) ist der Bauplan für gleichartige Objekte: Jedes Lastenrad hat eine Nummer und ein Modell, jedes kann gebucht werden. Im Diagramm ist sie ein Rechteck mit drei Fächern, von oben nach unten: Name, Attribute (was ein Objekt speichert) und Methoden (was ein Objekt kann), in UML auch Operationen (operations) genannt.

Lastenrad- radNr: int- modell: String- preisProStunde: double+ istVerfuegbar(): boolean+ berechnePreis(stunden: int): doubleKlassennameSubstantiv, Singular, großAttributeSichtbarkeit Name: TypMethodenSichtbarkeit Name(Parameter): Rückgabetyp

Attribute

Ein Attribut schreibst du als Sichtbarkeit name: Typ, zum Beispiel - radNr: int. Der Name beginnt klein, zusammengesetzte Wörter schreibst du im camelCase (preisProStunde). Ohne Datentyp gibt es in der Prüfung meist keinen vollen Punkt.

Methoden

Eine Methode schreibst du als Sichtbarkeit name(parameter: Typ): Rückgabetyp, zum Beispiel + berechnePreis(stunden: int): double. Mehrere Parameter trennst du mit Komma. Gibt eine Methode nichts zurück, ist der Rückgabetyp void. Auch eine Methode ohne Parameter bekommt die leeren Klammern: + stornieren(): void.

Sichtbarkeit

Das Zeichen vor jedem Attribut und jeder Methode legt fest, wer darauf zugreifen darf. Faustregel für die Prüfung: Attribute privat, Methoden öffentlich (Datenkapselung).

ZeichenSichtbarkeitZugriff
+public (öffentlich)Von überall zugreifbar. Typisch für Methoden.
-private (privat)Nur innerhalb der eigenen Klasse. Typisch für Attribute.
#protected (geschützt)In der Klasse und in ihren Unterklassen.
~package (Paket)Innerhalb desselben Pakets. In Prüfungen selten.

Assoziationen und Multiplizitäten

Eine Assoziation (association) ist eine durchgezogene Linie zwischen zwei Klassen und sagt: Objekte dieser Klassen kennen sich. Ein Kunde kennt seine Buchungen, eine Buchung kennt ihren Kunden. Erst die Beschriftung an den Linienenden macht daraus eine präzise Aussage.

Multiplizitäten

Die Multiplizität (multiplicity) gibt an, wie viele Objekte an einer Beziehung beteiligt sind. Die wichtigste Regel: Sie steht an der Klasse, deren Anzahl sie beschreibt. Du liest sie also von der gegenüberliegenden Klasse aus.

10..*legt an0..*1rad11..*Kunde- kundenNr: int- name: String- email: String+ aendereEmail(neu: String): voidBuchung- beginn: DateTime- ende: DateTime- status: String+ berechnePreis(): double+ stornieren(): voidLastenrad- radNr: int- modell: String- preisProStunde: double+ istVerfuegbar(): booleanStation- bezeichnung: String- adresse: String
Das fertige Klassendiagramm aus dem Beispiel unten. Die Multiplizitäten stehen in Akzentfarbe.

Die Linie zwischen Kunde und Buchung liest du in beide Richtungen: „Ein Kunde legt 0..* Buchungen an“, darum steht 0..* an Buchung. „Eine Buchung gehört zu 1 Kunden“, darum steht 1 an Kunde.

NotationBedeutungBeispiel
1genau einsJede Buchung hat genau einen Kunden.
0..1keins oder einsEin Mitarbeiter hat höchstens einen Dienstwagen.
*beliebig viele, auch keins (gleich 0..*)Ein Kunde hat beliebig viele Buchungen.
1..*mindestens einsEine Station hat mindestens ein Lastenrad.
2..4fester BereichEin Projektteam hat zwei bis vier Mitglieder.

Assoziationsname und Rollen

In der Mitte der Linie darf ein Assoziationsname stehen, meist ein Verb wie „legt an“. Er macht das Diagramm lesbarer, ist aber optional. Ein Rollenname (role) steht dagegen an einem Linienende und sagt, welche Rolle die Klasse dort spielt. Im Diagramm oben ist das Lastenrad für die Buchung das rad. Im Code wird aus dem Rollennamen später ein Attribut: - rad: Lastenrad in der Klasse Buchung.

Navigierbarkeit

Eine offene Pfeilspitze am Linienende bedeutet: Von der anderen Seite aus kommt man hierhin. Im Beispiel kennt die Buchung ihr Lastenrad, das Lastenrad muss seine Buchungen aber nicht kennen. Ohne Pfeilspitze ist die Navigierbarkeit offen; in Prüfungen wird eine solche Linie meist als „beide kennen sich“ gelesen. Zeichne Pfeile nur, wenn die Aufgabe eine Richtung verlangt oder sie eindeutig aus dem Text folgt.

Aggregation und Komposition in Kürze

Zwei Sonderformen der Assoziation beschreiben eine Teil-Ganzes-Beziehung. Die Raute sitzt dabei immer am Ganzen:

  • Aggregation (leere Raute): Die Teile gehören zum Ganzen, können aber auch ohne es existieren. Ein Team besteht aus Mitarbeitern; löst sich das Team auf, gibt es die Mitarbeiter weiterhin.
  • Komposition (gefüllte Raute): Die Teile existieren nur mit dem Ganzen und gehören zu genau einem Ganzen. Wird ein Gebäude abgerissen, sind auch seine Räume weg. Am Ganzen steht deshalb die Multiplizität 1 (oder 0..1).

Im Lastenrad-Beispiel ist die Beziehung zwischen Station und Lastenrad bewusst eine einfache Assoziation: Schließt eine Station, gibt es die Räder weiterhin. Eine Aggregation wäre ebenfalls vertretbar. Alle Linienarten auf einen Blick, vertieft werden Komposition und Vererbung in Lektion 4:

LinieNameBedeutung
AssoziationKlassen kennen sich. Navigierbarkeit nicht festgelegt.
Gerichtete AssoziationNur in Pfeilrichtung navigierbar.
AbhängigkeitGestrichelt, offene Spitze, z. B. «use»: Eine Klasse nutzt die andere vorübergehend.
AggregationTeil und Ganzes, leere Raute am Ganzen. Teile existieren auch allein.
KompositionTeil und Ganzes, gefüllte Raute am Ganzen. Teile leben und sterben mit dem Ganzen.
Vererbung (Generalisierung)Dreieck zeigt auf die Oberklasse. Lektion 4.

Beispiel Schritt für Schritt: Lastenräder

So sieht eine typische Prüfungsaufgabe aus. Lies den Text einmal ganz, dann gehst du in drei Schritten vor.

Ausgangssituation

Die Stadtwerke Mittelstadt planen eine Buchungsplattform für Lastenräder. Kunden registrieren sich mit Name und E-Mail-Adresse und erhalten eine Kundennummer; die E-Mail-Adresse soll sich später ändern lassen. Jedes Lastenrad hat eine Radnummer, ein Modell und einen Preis pro Stunde, und es soll abfragbar sein, ob es gerade verfügbar ist. Jedes Lastenrad gehört fest zu einer Station; eine Station hat eine Bezeichnung, eine Adresse und mindestens ein Lastenrad. Schließt eine Station, werden ihre Räder an andere Stationen verteilt. Ein Kunde kann beliebig viele Buchungen anlegen. Eine Buchung gilt für genau ein Lastenrad und speichert Beginn, Ende und Status. Die Plattform soll den Preis einer Buchung berechnen und Buchungen stornieren können.

Aufgabe: Erstellen Sie ein Klassendiagramm mit Attributen, Datentypen, Methoden, Beziehungen und Multiplizitäten.

Schritt 1: Klassen finden

Markiere alle Substantive (oben schon erledigt). Klassen sind die Substantive, die eigene Daten haben und mehrfach vorkommen: Kunde, Lastenrad, Station, Buchung. Die übrigen Substantive sortierst du aus: Name, Radnummer oder Adresse sind Eigenschaften, also Attribute. „Plattform“ ist das System selbst und „Stadtwerke“ der Auftraggeber; beide werden keine Klasse. Klassennamen schreibst du im Singular und groß.

KundeBuchungLastenradStation
Schritt 1: die vier Klassen

Schritt 2: Attribute und Methoden zuordnen

Jedes aussortierte Substantiv wandert als Attribut in seine Klasse, mit Sichtbarkeit und Datentyp. Aus den Verben, die eine Fähigkeit beschreiben, werden Methoden: E-Mail ändern, Verfügbarkeit abfragen, Preis berechnen, stornieren. Die Methode kommt in die Klasse, deren Daten sie braucht, berechnePreis() also in die Buchung, weil dort Beginn und Ende liegen.

Kunde- kundenNr: int- name: String- email: String+ aendereEmail(neu: String): voidBuchung- beginn: DateTime- ende: DateTime- status: String+ berechnePreis(): double+ stornieren(): voidLastenrad- radNr: int- modell: String- preisProStunde: double+ istVerfuegbar(): booleanStation- bezeichnung: String- adresse: String
Schritt 2: Attribute und Methoden, noch ohne Beziehungen

Zwei Details: Die Station hat im Text keine Methode, ihr Methodenfach bleibt leer. Und der Status ist hier ein String. Für feste Werte wie offen, aktiv und storniert wäre auch eine Aufzählung (enumeration) üblich; in der Prüfung ist ein String als einfache Lösung vertretbar.

Schritt 3: Beziehungen und Multiplizitäten

Jetzt suchst du die Sätze, die zwei Klassen verbinden, und formulierst jede Beziehung in beide Richtungen:

  • Ein Kunde legt beliebig viele Buchungen an, eine Buchung gehört zu genau einem Kunden: 1 an Kunde, 0..* an Buchung.
  • Eine Buchung gilt für genau ein Lastenrad, ein Lastenrad kann beliebig oft gebucht werden: 1 an Lastenrad, 0..* an Buchung. Die Buchung muss ihr Rad kennen, daher die Pfeilspitze und die Rolle rad.
  • Eine Station hat mindestens ein Lastenrad, jedes Lastenrad gehört fest zu einer Station: 1..* an Lastenrad, 1 an Station. Eine Aggregation wäre ebenfalls vertretbar, weil die Räder die Station überleben.
10..*legt an0..*1rad11..*Kunde- kundenNr: int- name: String- email: String+ aendereEmail(neu: String): voidBuchung- beginn: DateTime- ende: DateTime- status: String+ berechnePreis(): double+ stornieren(): voidLastenrad- radNr: int- modell: String- preisProStunde: double+ istVerfuegbar(): booleanStation- bezeichnung: String- adresse: String
Schritt 3: das fertige Klassendiagramm

Zeichenaufgaben

Zeichne erst selbst, dann klapp die Musterlösung auf und vergleiche Punkt für Punkt. Die Punkte sind Richtwerte im Stil der IHK; die tatsächliche Verteilung legt jede Prüfung selbst fest.

Zeichenaufgabe 3.1
Stadtbibliothek, Richtwert 10 Punkte

Die Stadtbibliothek möchte ihre Ausleihe digital verwalten. Leser haben eine Lesernummer, einen Namen und ein Geburtsdatum. Jedes Medium hat eine Mediennummer, einen Titel und ein Erscheinungsjahr. Bei jeder Ausleihe werden das Ausleihdatum und das Rückgabedatum gespeichert. Eine Ausleihe betrifft genau einen Leser und genau ein Medium. Ein Leser kann beliebig viele Ausleihen haben, ein Medium wird im Laufe der Zeit beliebig oft ausgeliehen. Eine Ausleihe kann um eine Anzahl von Tagen verlängert werden.

Aufgabe: Modellieren Sie die Klassen Leser, Medium und Ausleihe mit Attributen, Datentypen und der Methode zum Verlängern. Tragen Sie die Beziehungen mit Multiplizitäten ein.

Zeichne auf Papier oder im Diagramm-Tool nachzeichnen: Es steckt in den Übungsprüfungen und öffnet sich dort bei jeder Zeichenaufgabe.

Musterlösung anzeigen
10..*tätigt0..*1betrifftLeser- leserNr: int- name: String- geburtsdatum: DateAusleihe- ausleihdatum: Date- rueckgabedatum: Date+ verlaengern(tage: int): voidMedium- medienNr: int- titel: String- erscheinungsjahr: int

Die Ausleihe ist eine eigene Klasse, weil sie eigene Daten hat (Ausleih- und Rückgabedatum). Leser und Medium hängen deshalb nicht direkt zusammen, sondern über die Ausleihe. Eine Assoziationsklasse Ausleihe wird meist ebenfalls anerkannt (siehe Lektion 4). Die Unterscheidung in Buch, DVD und Zeitschrift ist hier nicht gefordert; sie wäre ein Fall für Vererbung (Lektion 4).

So wird typischerweise bewertet

  • 3 Punkte: je 1 Punkt für die Klassen Leser, Medium und Ausleihe.
  • 3 Punkte: Attribute vollständig mit Sichtbarkeit und Datentyp, je Klasse 1 Punkt.
  • 1 Punkt: verlaengern(tage: int): void in der Klasse Ausleihe.
  • 1 Punkt: beide Assoziationen zwischen den richtigen Klassen.
  • 2 Punkte: Multiplizitäten, je Beziehung 1 Punkt, nur wenn beide Enden stimmen.
  • Richtwert gesamt: 10 Punkte.
Zeichenaufgabe 3.2
Tierarztpraxis, Richtwert 11 Punkte

Eine Tierarztpraxis verwaltet ihre Patienten. Tierhalter werden mit Kundennummer, Name und Telefonnummer erfasst, und zwar erst, wenn sie mindestens ein Tier anmelden. Jedes Tier hat eine Chipnummer, einen Namen, eine Tierart und ein Geburtsdatum und gehört genau einem Tierhalter. Für ein Tier können beliebig viele Termine vereinbart werden; jeder Termin gilt für genau ein Tier und hat einen Beginn, eine Dauer in Minuten und einen Grund. Termine können abgesagt werden. Aus dem Geburtsdatum soll das Alter eines Tieres berechnet werden.

Aufgabe: Erstellen Sie ein Klassendiagramm mit Attributen, Datentypen, Methoden und Multiplizitäten. Vergeben Sie für die Beziehung zwischen Tier und Tierhalter am Tierhalter den Rollennamen besitzer.

Zeichne auf Papier oder im Diagramm-Tool nachzeichnen: Es steckt in den Übungsprüfungen und öffnet sich dort bei jeder Zeichenaufgabe.

Musterlösung anzeigen
1besitzer1..*10..*Tierhalter- kundenNr: int- name: String- telefon: StringTier- chipNr: String- name: String- tierart: String- geburtsdatum: Date+ berechneAlter(): intTermin- beginn: DateTime- dauerMin: int- grund: String+ absagen(): void

1..* steht am Tier, weil ein Tierhalter mindestens ein Tier hat. Der Rollenname besitzer steht am Tierhalter, denn er beschreibt die Rolle, die der Tierhalter für das Tier spielt. Chipnummer und Telefonnummer sind Strings: Man rechnet nicht mit ihnen, und führende Nullen oder ein Pluszeichen müssen erhalten bleiben. Das Alter ist kein Attribut, sondern wird mit berechneAlter() aus dem Geburtsdatum berechnet.

So wird typischerweise bewertet

  • 3 Punkte: je 1 Punkt für die Klassen Tierhalter, Tier und Termin.
  • 3 Punkte: Attribute mit Sichtbarkeit und passendem Datentyp, chipNr und telefon als String.
  • 2 Punkte: berechneAlter(): int in Tier und absagen(): void in Termin.
  • 2 Punkte: Multiplizitäten 1 zu 1..* und 1 zu 0..*, jeweils am richtigen Ende.
  • 1 Punkt: Rollenname besitzer am Ende der Klasse Tierhalter.
  • Richtwert gesamt: 11 Punkte.

Typische Fehler

Jetzt selbst testen

Fünf Fragen zur Notation. Du hast so viele Versuche, wie du willst.

1 / 5

Zwischen Kunde und Bestellung steht an Kunde eine 1 und an Bestellung ein *. Was bedeutet das?

2 / 5

„Jede Station hat mindestens ein Lastenrad.“ An welches Linienende schreibst du 1..*?

3 / 5

Was bedeutet das Zeichen # vor einem Attribut?

4 / 5

Welche Methode ist nach UML korrekt notiert?

5 / 5

Ein Raum gehört zu genau einem Gebäude und wird mit dem Gebäude abgerissen. Wie modellierst du das?