Start
Unternehmen
Buch-Katalog
Seminare
Leserservice
Comelio-Blog
Datenbanken
SQL
MS SQL Server
Oracle
PHP
UML

Basis

Klasse

Use Cases

Verhalten

Interaktion

Aktivität

C#.NET
XML Schema
XSLT

Übersicht

Comelio GmbH
Rellinghauser Straße 10
D-45128 Essen
Deutschland
Fon: 0201-437517-0
Fax: 0201-437517-10
info@comelio.com

Comelio GmbH
Goethestraße 34
D-13086 Berlin
Deutschland
info@comelio.com

Comelio GmbH (Ecos)
Glockengießerwall 17
D-20095 Hamburg
Deutschland
info@comelio.com

Comelio GmbH (Ecos)
Mainzer Landstraße 27-31
D-60329 Frankfurt
Deutschland
info@comelio.com

Comelio GmbH (Ecos)
Stiglmaierplatz/Dachauer Str. 37
D-80335 München
Deutschland
info@comelio.com

Comelio GmbH (Ecos)
Liebknechtstr. 33
D-70565 Stuttgart
Deutschland
info@comelio.com

Comelio GmbH
Nevinghoff 16
D-48147 Münster
Deutschland

Comelio GmbH
Friedrich - List - Platz 1
D-04103 Leipzig
Deutschland

Comelio GmbH
St. Johanner Strasse 41-43
D-66111 Saarbrücken
Deutschland

Comelio GmbH
Kaiser-Wilhem-Ring 27–29
D-50672 Köln
Deutschland

Comelio GmbH
Münsterstraße 248
D-40470 Düsseldorf
Deutschland

Comelio GmbH
Fürther Strasse
D-90429 Nürnberg
Deutschland

Comelio GmbH

Bremen
Deutschland

Comelio-Blog > UML > Klasse

Klassendiagramme mit der UML

Das Einsatzgebiet der Klassendiagramme beginnt mit dem Projekt, in den meisten Fällen nach der Erstellung der Anwendungsfallanalyse und des Aktivitätsdiagramms. Es ist durchaus sinnvoll, bereits in der Analysephase mit den Klassendiagrammen zu beginnen. Hier würde man sicherlich noch nicht detailliert planen, sondern eine erste Grobplanung erstellen. Letztendlich wird während des Projekts noch einiges geändert, und das Klassendiagramm bietet eine gute Hilfestellung, um die Komplexität einer Anwendung beziehungsweise eines Teiles davon aufzunehmen und zu beschreiben. Während der Erfassung der Kundenwünsche sollen erst einmal die allgemeinen Zusammenhänge mit Hilfe des Klassendiagramms grundlegend beschrieben werden. Die Details werden erst dann hinzugefügt oder geändert, wenn die einzusetzende Technik, Technologie, ja in manchen Fällen sogar die Programmiersprache feststeht. Im ersten Schritt fehlen häufig die Datentypen, Schnittstellen und Methoden, und die Klasse erfasst auch namentlich erst einmal nur die Aufgabe, für die sie später zuständig ist. Ein Klassendiagramm enthält alle Informationen über die eigentliche Programmierung, der enthaltenen Eigenschaften und Funktionalitäten der Klassen und der Beziehung der Klassen untereinander.

Kontakt

Anrede* Herr Frau
Vorname*
Nachname*
Firma
E-Mail*
Tel-Nr.
Bereich*
Freitext

Klassendiagramme

Einsatzgebiete

Das Einsatzgebiet der Klassendiagramme beginnt mit dem Projekt, in den meisten Fällen nach der Erstellung der Anwendungsfallanalyse und des Aktivitätsdiagramms. Es ist durchaus sinnvoll, bereits in der Analysephase mit den Klassendiagrammen zu beginnen. Hier würde man sicherlich noch nicht detailliert planen, sondern eine erste Grobplanung erstellen. Letztendlich wird während des Projekts noch einiges geändert, und das Klassendiagramm bietet eine gute Hilfestellung, um die Komplexität einer Anwendung beziehungsweise eines Teiles davon aufzunehmen und zu beschreiben. Während der Erfassung der Kundenwünsche sollen erst einmal die allgemeinen Zusammenhänge mit Hilfe des Klassendiagramms grundlegend beschrieben werden. Die Details werden erst dann hinzugefügt oder geändert, wenn die einzusetzende Technik, Technologie, ja in manchen Fällen sogar die Programmiersprache feststeht. Im ersten Schritt fehlen häufig die Datentypen, Schnittstellen und Methoden, und die Klasse erfasst auch namentlich erst einmal nur die Aufgabe, für die sie später zuständig ist. Ein Klassendiagramm enthält alle Informationen über die eigentliche Programmierung, der enthaltenen Eigenschaften und Funktionalitäten der Klassen und der Beziehung der Klassen untereinander.

Das Metamodell Klassendiagramme

Abbildung 6.1: Subpackages der Klassenpakete und deren Abhängigkeiten zeigt die Unterpakete von den Klassendiagramme und deren Abhängigkeiten:

Abbildung 
  6.1: Subpackages der Klassenpakete und deren Abhängigkeiten

In den meisten Programmiersprachen wie C# oder Java gibt es eine allgemeine Oberklasse, die in C# und Java jeweils Object heißt. Von dieser Oberklasse erben alle Klassen, die programmiert werden. Dieses Konzept spiegelt sich auch in der UML 2.0 wider. Somit gibt es eine Oberklasse mit dem Namen Element, von der alle Elemente erben. Diese Oberklasse ist abstrakt, von ihr kann also selbst keine Instanz gebildet werden. Sie bildet stattdessen ein allgemeines Konzept, dessen konkrete Ausprägungen in Unterklassen dargestellt werden. Sie darf explizit weitere Elemente enthalten, was sich im Metamodell beschrieben wiederfindet. Die Darstellung von Element sehen Sie im Folgenden:

Abbildung 
  6.2: Basisklasse der UML 2.0

Zunächst einmal gibt es in der UML 2.0 den Begriff eines benennbaren Elements (NamedElement). Solch ein benennbares Element kann einen Namen haben und ist nach außen mit einer Sichtbarkeit verbunden. Eines dieser benennbaren Elemente in der UML 2.0 ist beispielsweise eine Klasse. Eine Klasse soll innerhalb eines Systems genau eine Aufgabe übernehmen. Somit übernimmt die Klasse eine Verantwortung für einen sachlogischen Aspekt des Gesamtsystems.

Im Kontext sieht wie in Abbildung 6.3: RootDiagramm aus:

Abbildung 
  6.3: RootDiagramm

Sie sehen in vorheriger Abbildung, dass man jederzeit an ein Element einen Kommentar anhängen kann. Dieser Kommentar gehört zum Element selbst, was in der Abbildung anhand der Kompositionsbeziehung ersehen können. Diese Kompositionsbeziehung stellt entsprechend den Kommentar als Eigentum des Elementes dar. Dabei kann ein Element beliebig viele Kommentare enthalten, umgekehrt auch ein Kommentar beliebig vielen Elementen gehören. Es gibt beim Kommentar noch eine andere Möglichkeit, das Element anzubringen, nämlich als angeheftetes Element (Spezifikation: +annotatedElement). Hierbei kann ein Kommentar ebenfalls beliebig vielen Elementen angeheftet werden.

In der Spezifikation beschrieben ist das Namespace Diagram aus Abbildung 6.4: Namespaces. Dieses steht in einer Kompositionsbeziehung zu NamedElement. Zusätzlich gibt es noch eine gerichtete Assoziation, wobei der Namespace mehrere Benannte Elemente enthalten darf.

Abbildung 
  6.4: Namespaces

Im Namespace können die verschiedenen Enumerationen der VisibilityKinds angebracht werden:

  • Public
  • Private
  • Protected
  • Package

Schaut man einmal auf den Import, so unterscheidet man hier zwischen Elementimport und Packageimport. Wir werden später in diesem Kapitel darauf noch genauer eingehen. Die Verhältnisse sind hier ebenfalls für die Prüfungen wichtig, es handelt sich hier um eine Kompositionsbeziehung, was bedeutet, dass die importierten Packages und Elemente fest zum Namespace gehören. Ein Namespace darf immer beliebig viele Importe zulassen, umgekehrt aber gehört immer ein Import zu einem einzigen Namespace.

Die Muliplizitäten sind Teil der Abbildung 6.5: Multiplizitäten:

Abbildung 
  6.5: Multiplizitäten

Zunächst zu einem typisierbaren Element (Spezifikation TypedElement). Es handelt sich dabei grundsätzlich um ein benanntes Element, was Sie in Abbildung vorheriger an der Generalisierungsbeziehung ersehen können. Ein typisierbares Element hat grundsätzlich keinen oder einen Typ.

Die Multiplizität, die dieses Diagramm eigentlich beschreibt, stellt definiert ein Intervall dar und deutet die Anzahl der möglichen Kardinalitäten (Spezifikation: Cardinality) an, die die Anzahl der möglichen Ausprägungen darstellt. Dazu später mehr.

Eine Wertespezifikation (Spezifikation: ValueSpecification) stellt eine Spezifikation der Werte in einem Modell dar. Es handelt sich dabei um einfache formale Ausdrücke. Diese Ausdrücke können aus der Programmiersprache sein, in denen man sie beschreibt, also zum Beispiel Java, C++, OCL etc. Der Fachbegriff hierzu heißt: OpaqueExpression. Wichtig für die Prüfung: Die Angabe der Sprache kann weggelassen werden, wenn sie aus dem Kontext verständlich ist. Wenn man die Sprache angeben will, so erfolgt dies mit der Sprachangabe in geschweiften Klammern.

Abbildung 
  6.6: Expressions

Literale wie in Abbildung 6.6: Expressions stellen Spezialisierungen der Klasse LiteralSpecification dar, wobei diese wiederum von ValueSpecification abgeleitet ist, wie Sie aus Abbildung ersehen können. Dabei gibt es folgende Literale:

  • LiteralBoolean
  • LiteralInteger
  • LiteralString
  • LiteralUnlimitedNatural
  • LiteralNull

Dies ist hier noch einmal besonders erwähnt, da es eine Frage in der Prüfung sein kann.

Eine Zusicherung (Spezifikation: Constraint) ist eine Bedingung, die für ein Element erfüllt sein muss. Es kann sich dabei um einen OCL-Ausdruck handeln, zugelassen ist aber auch ein sprachlicher Ausdruck.

In nachfolgender Abbildung ist das Metamodell zu den Constraints:

Abbildung 
  6.7: Constraints

Eine Instancespecification, dargestellt in Abbildung 6.8: Instanzspezifikation stellt eine konkrete Ausprägung dar. Der so genannte Slot, den Sie in vorheriger Abbildung sehen, stellt die einzelnen Werte in einem Objekt dar. Grundsätzlich ist erlaubt, dass die Angaben unvollständig sind.

Abbildung 
  6.8: Instanzspezifikation

In Abbildung 6.9: Classes sehen Sie die Modelle für den vorheriger Classifier und die dazugehörigen Merkmale.

Abbildung 
  6.9: Classes

Der Classifier kann mehrere Eigenschaften (Spezifikation:Properties) enthalten, wobei eine Eigenschaft immer zu 0 oder einem Classifier gehört. Eine genauere Beschreibung der Classifier gibt es nachfolgend in diesem Kapitel.

Ein Feature beschreibt einige Verhaltensmerkmale oder Strukturmerkmale der Objekte einer Klasse, wie Sie in der Abbildung 6.10: erkennen.

Abbildung 
  6.10: Feature

Ein StructuralFeature ist beispielsweise die Eigenschaft, die in Abbildung 6.10: Feature auch mit einem Attribut isReadOnly versehen werden kann, das angibt, dass das entsprechende Attribut nicht mehr verändert werden kann.

Ein BehavioralFeature hingegen ist beispielsweise eine Operation. Hierbei geht es, wie aus dem Namen schon zu sehen, grundsätzlich um Verhalten. Es können Parameter übergeben werden, und zwar wie in Abbildung 6.10: Feature ersichtlich, anhand der Multiziplitäten beliebig viele. Der Parameter hat dabei eine Richtung und gehört BehavioralFeature, was man an der Kompositionsbeziehung erkennt. Über die Richtungen werden wir nachfolgend noch Genaueres angeben.

Abbildung 6.11: Operations zeigt die Operationen und deren formale Verhältnisse und Regelungen:

Abbildung 
  6.11: Operations

Die Operation ist wiederum ein Verhaltensmerkmal und steuert auch das Verhalten. Die Syntax und den praktischen Einsatz werden wir zu einem späteren Zeitpunkt in diesem Kapitel vorstellen. Hier soll zunächst das Metamodell erläutert werden:

Wie Sie sehen, gibt es grundsätzlich Vor- und Nachbedingungen. Zu den Operationen gehören per Kompositionsbeziehung die Parameter, Constraints und Typen.

In der Spezifikation kommt danach die Beschreibung der Properties. Die Eigenschaften können auch per Assoziation beschrieben werden. Wie schon erwähnt, stellen die Eigenschaften ein StructuralFeature dar

Abbildung 
  6.12: Properties

Die Assoziation ist inAbbildung 6.12: Properties ebenfalls ein Thema. Zur Assoziation gehören beliebig viele Eigenschaften.

Pakete, wie in beschrieben besitzen grundsätzlich jeweils beliebig viele Elemente und Typen. Später im Kapitel wird noch genau erläutert, wie der PackageMerge grundsätzlich in der Praxis verläuft.

Abbildung 
  6.13: Packages

Bei den Abhängigkeiten handelt es sich um Beziehungen von Elementen. Dabei geht es um Quellelemente (Spezifikation: +supplier) und um clients, die das Ziel darstellen. Die genauere Notation wird nachfolgend im Kapitel noch aufgezeigt, hier an dieser Stelle zunächst das Metamodell in Abbildung 6.14: Abhängigkeiten

Abbildung 
  6.14: Abhängigkeiten

Bei den Schnittstellen handelt es sich um eine vertragliche Vereinbarung darüber, welche Merkmale die einbindenden Klassen später enthalten sollten. Sie können grundsätzlich jeweils beliebig viele Eigenschaften und Operationen enthalten, wie Sie in Abbildung 6.15: Interfaces an der Kompositionsbeziehung ersehen können. Umgekehrt gehören die Eigenschaften und Operationen selbst immer keinem oder einem Interface.

Abbildung 
  6.15: Interfaces

Notation der Klassendiagramme

Die Klasse

Zunächst einmal gibt es in der UML 2.0 den Begriff eines benennbaren Elementes (NamedElement). Solch ein benennbares Element kann einen Namen haben und ist nach außen mit einer Sichtbarkeit verbunden. Eines dieser benennbaren Elemente in der UML 2.0 ist beispielsweise eine Klasse. Eine Klasse soll innerhalb eines Systems genau eine Aufgabe übernehmen. Somit übernimmt die Klasse eine Verantwortung für einen sachlogischen Aspekt des Gesamtsystems. Die Member dieser Klasse, also alle Attribute und Methoden, führen wiederum Aufgaben in einer Klasse aus, die in diesem Verantwortungsbereich liegen.

Zunächst einmal wird eine Klasse durch ein dreigeteiltes Rechteck dargestellt. Der Klassenname steht in der Mitte des obersten Rechtecks, wie in Abbildung 6.16: Eine einfache Klasse mit fehlenden Attributen und Operationen

Abbildung 
  6.16: Eine einfache Klasse mit fehlenden Attributen und Operationen

Die in dem Rechteck vorhandene Unterteilung kann (oder sollte sogar) im ersten Analyseschritt weggelassen werden, wenn es sich lediglich um die Beschreibung der Klasse handelt. In der Unterteilung kommt später in der ersten Unterteilung die Datentypen und in der zweiten die Methoden oder in der UML 2.0 die Operationen der. In dem ersten Schritt, der Beschreibung der Aufgabe der Klasse, ist es zunächst wichtig, einen aussagekräftigen Klassennamen zu benutzen.

In der Analysephase, in der es darum geht, zunächst einmal alle notwendigen Klassen ausfindig zu machen, sollte die Klasse also tatsächlich wie in Abbildung 6.17: Eine einfache Klasse ganz ohne Attribute und Methoden dargestellt aussehen:

Abbildung 
  6.17: Eine einfache Klasse ganz ohne Attribute und Methoden

In diesem Beispiel handelt es sich um die Klasse Person. Erst in einem nächsten Schritt sollte genauer geklärt werden, welche Eigenschaften die Person haben kann, welche davon wichtig für die Modellierung des Systems sind und schließlich, was die Person alles tun und erledigen kann.

Die Klasse wird also im nächsten Schritt unterteilt, und es werden die so genannten Eigenschaften und Operationen (Spezifikation: attributes, operations) in zwei weiteren rechteckförmigen Unterteilungen innerhalb der Klasse untergebracht, wie in Abbildung 6.18: Eine Klasse mit Attributen und Operationen dargestellt:

Abbildung 
  6.18: Eine Klasse mit Attributen und Operationen

Die erste Unterteilung enthält die Attribute und die zweite Unterteilung enthält die Methodendeklarationen. Aus diesem Konstrukt erstellen einige Tools mehr oder weniger guten Quellcode in einer konkreten Programmiersprache.

Nachfolgend werden wir meistens die letzte Notation der Klasse mit dieser Unterteilung nehmen, obwohl wir dabei nicht immer die Attribute und Operationen angeben. Wenn die Attribute und die Operationen nicht angegeben werden, ist natürlich auch die Notation wesentlich einfacher und oftmals in der Literatur gebräuchlicher.

In der Spezifikation ist im Paket Kernel des Metamodells genau beschrieben. Dabei hat die UML 2.0, wie die meisten der objektorientierten Programmiersprachen, eine Oberklasse. In Java und in C# heißt diese Oberklasse Object. Hier in der UML-2.0-Spezifikation heißt sie Element. Soweit zur Theorie, denn das Element als oberste Basisklasse wird sicherlich niemand einsetzen, so viel ist sicher. Nur Klassen, die von Element erben, dürfen im Übrigen überhaupt instanziert werden, da die Klasse Element selbst

abstract
ist. Dies bedeutet nämlich, dass von der Klasse geerbt werden darf, und von den Erblingen auch Instanzen gebildet werden können. Allerdings kann von einer abstrakten Klasse selbst keine Instanz gebildet werden. Somit vererbt die Klasse Element an alle Elemente der UML 2.0. Jedes Element hat somit alle Member von Element geerbt.

Objekte und Instanzspezifikation

Während eine Klasse eine Schablone darstellt, ist das Objekt eine konkrete Ausprägung dieser Klasse. In der UML 2.0 unterliegt dieser Formalismus der Instanzspezifikation (Spezifikation: InstanceSpecification). Die genauen Werte für ein solches Objekt, also die genauen Attributwerte, nennen sich Slots.

Ein konkretes Objekt sieht dann wie in Abbildung 6.19: Objekt aus.

Abbildung 
  6.19: Objekt

Ein Objekt kann die Klasse enthalten, von der es konkret abgeleitet wird. Hier in unserem Beispiel handelt es sich um die Klasse

Person
. Der gesamte Aufbau ist dem der Klasse ähnlich, bis auf die Tatsache, dass der Name des Objekts unterstrichen wird. Zudem haben natürlich die Attribute konkrete Werte. Es ist im Übrigen nicht zwingend, für alle Attribute entsprechende Werte anzugeben.

Attribute

In der UML 2.0 gibt es ein typisierbares Element (TypedElement). Es handelt sich dabei um ein benennbares Element (NamedElement), das neben einem Namen auch einen Typ haben kann. Attribute und Parameter sind beispielsweise solche Elemente.

Eine Wertespezifikation (ValueSpecification) drückt einen Wert in einem Modell aus. Es handelt sich dabei letztendlich nur um mathematische Ausdrücke, die sich errechnen lassen.

Ein Attribut muss innerhalb der Klasse eindeutig definiert sein. Die Attribute können mit folgender Syntax noch weiter spezifiziert werden:

[Sichtbarkeit] [/] name [:Typ] [Multiplizität] [= Vorgabewert] [{Eigenschaftswert}]

In folgender Tabelle finden Sie eine Übersicht über die Merkmale der Syntax:

Deklaration eines Attributs Bedeutung
Sichtbarkeit
(Spezifikation: visibility)
Die Sichtbarkeit für das nachfolgende Attribut bestimmt, wie von außerhalb der Klasse auf das Attribut oder seinen Wert zugegriffen werden kann. Es gibt in der UML 2.0 vier verschiedene Sichtbarkeitsmodi, die zudem auch für Methoden gelten. In der nachfolgenden Tabelle unterscheiden wir diese.
/ Es handelt sich um ein abgeleitetes Attribut. Somit werden die Werte zur Laufzeit berechnet und daher brauchen die Daten nicht vorab gespeichert zu werden.
name Der Name des Attributes ist grundsätzlich zwingend anzugeben.
[:Typ][Multiplizität]
(Spezifikation: multiplicity)
Hier wird der Typ des Attributes festgelegt. Mit der Multiplizität wird die Unter- und Obergrenze der Anzahl der unter einem Attributnamen ablegbaren Ausprägungen festgelegt. In einer nachfolgenden Tabelle werden wir die verschiedenen Möglichkeiten der Multiplizität aufschlüsseln.
In der Literatur ist auch häufig die Rede von der Kardinalität. Dies ist die Ausprägung bei konkreten Objekten und sie haben mit dem Objektmodell zu tun, nicht aber mit dem Klassenmodell.
Vorgabewert
(Spezifikation: default)
Der Vorgabewert ist der Default-Wert des Attributs, der automatisch als Erstes gesetzt wird, und zwar nur, wenn zur Laufzeit eine Methode diesen Wert nicht verändert.
Eigenschaftswert
(Spezifikation: property-string)
Mit den Eigenschaftswerten, die in geschweiften Klammern angegeben werden, können nun Einschränkungen festgelegt werden. Auch hier haben wir in einer nachfolgenden Tabelle die möglichen Werte aufgezeigt.

Tabelle 6.1: Allgemeine Syntax der Attributdeklaration

Kommen wir zunächst auf die Sichtbarkeit zurück. Die nachfolgende Tabelle schlüsselt die einzelnen Sichtbarkeitsschlüsselwörter und deren Notation in der UML 2.0 auf:

Schlüsselwort Notation Bedeutung
public
+ Die Sichtbarkeit auf dieses Element kann von überall her erfolgen.
private
- Die Sichtbarkeit auf dieses Element kann nur innerhalb der eigenen Klasse erfolgen.
protected
# Die Sichtbarkeit auf dieses Element kann in allen abgeleiteten Klassen und natürlich in der eigenen Klasse erfolgen. Von außen ist ein Zugriff nicht möglich.
package
~ Die Sichtbarkeit gilt hier für alle definierten Klassen in demselben Paket der Klasse.
static
Das Element ist unterstrichen. Das Element ist auch ohne Objekt sichtbar und zugreifbar.

Tabelle 4.2: Schlüsselwörter

Kümmern wir uns nun um die so genannte Multiziplität. Die Multiziplität wird von eckigen Klammern umschlossen und legt jeweils die Unter- und Obergrenze der Ausprägungen eines Attributes fest. Und nicht nur in diesem Zusammenhang gibt es die Multiplizität (Spezifikation: MultiplicityElement). Wenn die Multiziplität die Möglichkeiten der Ausprägungen anzeigt, redet man von Kardinalität (Spezifikation: Cardinality), wenn man die Anzahl der Elemente in einer Menge benennen möchte. Hierbei handelt es sich also um die konkrete Anzahl der Ausprägungen. Nachfolgende Tabelle schlüsselt im Einzelnen die Möglichkeiten auf, die Multiziplität anzugeben.

Multiplizität Bedeutung
0..1 Das Attribut kann entweder keinen oder einen Wert annehmen.
1..1 Das Attribut muss zwingend mit genau einem Wert belegt werden. Es gilt auch die vereinfachende Schreibweise »1«.
0..* Das Attribut kann beliebig viele Werte annehmen.
1..* Das Attribut muss mindestens einen Wert haben, kann aber beliebig viele Werte annehmen.
n..m Das Attribut muss mindestens n Werte annehmen, kann aber bis zu m Werte annehmen.
n..n Das Attribut muss genau n Werte annehmen.

Tabelle 4.3: Multiziplitäten

Der Vorgabewert setzt quasi den Wert des Attributs per Default. Zunächst ist also der Wert des Attributes gesetzt, kann später allerdings zur Laufzeit verändert werden.

Der Eigenschaftswert wird in geschweiften Klammern mitgeführt. Mit dem Eigenschaftswert können Sie die Eigenschaften des Attributs genauer festlegen. In folgender Tabelle sind die laut der Spezifikation möglichen Eigenschaftswerte aufgeführt:

Eigenschaftswert Bedeutung
readOnly
Nur lesender Zugriff auf den Eigenschaftswert erlaubt.
union

Mit dem Eigenschaftswert union definieren Sie eine gemeinsame Verwendung von Attributen für einen Oberbegriff. Die Zuordnung erfolgt in einem nächsten Schritt durch die Subsets.

Mit dem Eigenschaftswert union definieren Sie eine gemeinsame Verwendung von Attributen für einen Oberbegriff. Die Zuordnung erfolgt in einem nächsten Schritt durch die Subsets.
Beispiel: Adresse: String {union}
Später werden dann die einzelnen Attribute zu den Subsets, in diesem Falle zu Adresse, hinzugefügt.

subsets
Die Attribute werden durch subsets zusammengefasst.
Beispiel: Wohnort{subsets Adresse}
redefines
Die derzeitige Definition eines Attributes wird überschrieben.
Beispiel: NeuerWohnort{redefines Wohnort}
ordered
Der Eigenschaftswert ordered sorgt dafür, dass die Attributinhalte in einer stringenten Reihenfolge angeordnet werden und eindeutig sind.
Beispiel: {a, b, c, d}
bag
Mit diesem Eigenschaftswert legt man fest, dass Attribute ungeordnet sein können und auch nicht zwingend eindeutig sein müssen.
Beispiel: {c, a, b, a}
sequence
oder
seq
Mit diesem Eigenschaftswert legt man fest, dass die Attribute wie bei ordered geordnet sein müssen, allerdings müssen sie nicht eindeutig sein.
Beispiel: {a, b, c, c}
composite
Mit diesem Eigenschaftswert legt man fest, dass das Attribut selbst die eigenen Werte zerstört.

Tabelle 4.4 Eigenschaftswerte:

Hinter dem Element kann auch in geschweiften Klammern eine Zusicherung (Spezifikation: Constraint) notiert werden. Diese Zusicherung definiert mit Hilfe eines booleschen Ausdrucks, welcher Wertebereich zulässig ist. Zusicherungen werden grundsätzlich in geschweifte Klammern gefasst. Erlaubt ist die Zusicherung bei einem Element direkt hinter dem Namen oder innerhalb eines Kommentars, der direkt mit dem Element verbunden wird.

Die Syntax für eine Zusicherung sieht wie folgt aus:

`{` [<name> `:`] <boolean expression> `}`

Methoden

Eine Methode wird in der UML 2.0 auch als Operation (Spezifikation: operation) bezeichnet. Auch eine Methode muss innerhalb der Klasse eindeutig sein. Die Syntax sieht wie folgt aus:

[Sichtbarkeit] Name (Parameterliste) : Rückgabetyp [{Eigenschaftswert}]

Die Parameterliste wird entsprechend der folgenden Syntax beschrieben:

[Übergaberichtung] Name : Typ [`[`Multiplizität`]`] [= Vorgabewert] 
  [`{`Eigenschaftswert`}`]

Vieles, was zu den Attributen gesagt wurde, gilt auch uneingeschränkt über für die Methoden. Wir werden an entsprechender Stelle bei den Methoden darauf verweisen, was ähnlich ist.

  • Die Sichtbarkeit regelt, wie bei den Attributen, den Zugriff auf Methoden. Die Notation ist identisch mit der Notation der Methoden.
  • Der Name ist innerhalb einer Klasse eindeutig.

Die so genannte Übergaberichtung des Parameters (Spezifikation: ParameterDirectionKind) kann folgende Schlüsselwörter enthalten:

Schlüsselwort Bedeutung
in
Der Wert des Parameters wird von der aufrufenden Methode übergeben.
out
Der Wert des Parameters wird an die aufrufende Methode zurückgegeben.
inout
Der Wert des Parameters wird als Erstes von der aufrufenden Methode übergeben und danach an die aufrufende Methode zurückgegeben.
return
Mit
return
wird der Rückgabewert definiert.

Tabelle 4.5 ParameterDirectionKind:

Beispiel

Im Folgenden werden wir Ihnen ein zusammenfassendes Beispiel mit je einem Attribut und einer Methode zeigen:

Abbildung 
  6.20: Zusammenfassendes Beispiel einer Klasse mit einem Attribut und einer Methode

Wie Sie in dem Beispiel sehen, wird eine Eigenschaft

seminartitel
als String deklariert. Dieses Attribut hat die Multiplizität 1..*, was in diesem Kontext bedeutet, dass mindestens ein Seminartitel als Eigenschaft existieren muss, aber beliebig viele Seminartitel existieren können. Das Attribut ist als private deklariert und kann somit nur innerhalb der Klasse selbst genutzt werden. Von außen bleibt diese Eigenschaft unsichtbar. Der Standardwert (Spezifikation: default) ist
UML 2.0
, was hier nach dem Gleichheitszeichen folgt. Die Eigenschaft
SeminarPreis
ist ebenfalls
private
. Sie enthält hier die Zusicherung (Spezifikation: Constraint), dass der Wert mindestens
670 Euro
betragen muss.

Die Methode

BucheSeminar
ist mit dem Schlüsselwort
public
definiert. Die Methode hat einen Parameter namens
SeminarTitel
, der wiederum vom Typ
String
ist. Durch das Schlüsselwort
void
wird der Methode (Spezifikation: operation) mitgegeben, dass sie selbst keinen Rückgabewert hat. Sie gibt also keinen Wert zurück, sondern verarbeitet nur intern die Parameter, die ihr mitgegeben wurden. Die Methode
SeminarPreis
hat einen Rückgabewert vom Typ
Integer
. Diese Methode gibt also einen Wert zurück, wenn sie aufgerufen wird. Dieser zurückgegebene Wert ist in jedem Fall vom Typ
integer
. Zudem ist diese Methode statisch, kann also ohne die Erzeugung eines Objektes genutzt und von außen gesehen werden. Gekennzeichnet wird dies in der UML 2.0 dadurch, dass die ganze Methode unterstrichen wird.

Beachten Sie bitte, dass wir hier nur ein kleines Beispiel benutzen, um die Syntax von UML 2.0 zu erläutern. Die eigentliche Umsetzung erfolgt ja durch eine konkrete Programmiersprache wie C# oder Java.

Kommentare

An eine Klasse sowie an jedes andere Element aus der UML 2.0 können Kommentare (Spezifikation: Comment) angehangen werden. In der Spezifikation ist die Klasse

Comment
direkt mit der Basisklasse Element assoziiert, was diese Tatsache direkt untermauert. Diese Kommentare sind wie folgt in der UML 2.0 standardmäßig zu notieren:

Abbildung 
  6.21: Kommentar

Wie schon im vorherigen Satz verraten, kann man den Kommentar an jedem UML-Modellelement notieren. Dies begründet sich darin, dass die Klasse

Comment
direkt eine Assoziation mit der Basisklasse
Element
besitzt.

Schnittstellen

Schnittstellen (Spezifikation: interfaces) sind quasi ein Vertrag, den eine Klasse mit einer Schnittstelle schließt. Somit werden Methoden und

set-
und
get-
Methoden in der Schnittstelle definiert. Damit verpflichtet sich die Klasse, die Methode (Spezifikation: operation) der Schnittstelle zu definieren. Das Gleiche gilt hier auch für Attribute, auch wenn die meisten Programmiersprachen diese als Eigenschaftsmethoden bezeichnen. Die genaue Ausprogrammierung geschieht in der Klasse. Die Schnittstelle besteht daher nur aus den Methodenrümpfen und den Ein- und Ausgabeparametern. Ein Classifier (in den meisten Fällen wohl eine Klasse) kann beliebig viele Schnittstellen implementieren. Selbstverständlich kann die Klasse darüber hinaus weitere Methoden und Eigenschaften enthalten. Schnittstellen können untereinander jederzeit erweitert werden und voneinander erben. Hierbei wird die Generalisierungsbeziehung genutzt.

Es gibt im Prinzip nunmehr zwei Möglichkeiten, eine Schnittstelle anzubringen. Somit gibt es eine bereitgestellte Schnittstelle und eine benötigte Schnittstelle. Im ersten Fall bietet eine Schnittstelle ein Modellelement an und kann von anderen Modellelementen genutzt werden. Im anderen Fall handelt es sich um eine Schnittstelle, die von einem anderen Modellelement eingefordert wird.

Nun stellt sich natürlich die Frage, wie eine Schnittstelle implementiert wird. Dazu gibt es die Implementierungsbeziehung (Spezifikation: implementation), die eine spezielle Form der Realisierungsbeziehung darstellt. Zu der Realisierung, in der Programmierung zumeist Vererbung genannt, kommen wir im nächsten Abschnitt.

Grundsätzlich wird das Interface genauso notiert wie die Klasse. Zusätzlich enthält dieser Classifier allerdings das Schlüsselwort

<<interface>>.
Das Schlüsselwort steht über dem Namen des Classifiers, ähnlich wie, aber nicht zu verwechseln wie mit einem Stereotyp. Stereotypen sind nicht Teil der Fundamental-Prüfung und die Logik dahinter ist nicht trivial und genauestens in der Spezifikation beschrieben.

Abbildung 
  6.22: Beispiel eines Interface

Die Schnittstelle wird in der Klasse realisiert und steht somit in einer Realisierungsbeziehung (Spezifikation: realize). Nachfolgend wird die standardmäßige Notation verwendet.

Abbildung 
  6.23: Abbildung einer Realisierungsbeziehung

Oftmals ist in der Literatur und auch in der Spezifikation an dem Pfeil (Spezifikation: Dependency-Pfeil) das Schlüsselwort

<<realize>>
angezeigt, wie hier auch geschehen.

Es gibt noch eine weitere Möglichkeit, die Realisierung eines Interface zu notieren. In Abbildung 6.24: Realisierungsbeziehung mit der Steckernotation wird diese Möglichkeit aufgezeigt.

Abbildung 
  6.24: Realisierungsbeziehung mit der Steckernotation

Die Notation aus der Abbildung nennt sich Steckernotation und ist die abgekürzte Notation, die gleichbedeutend mit der Abbildung ist. Allerdings zeigt diese Kurznotation nur die Namen der Schnittstelle, nicht die enthaltenen Operationen und Attribute.

Für geforderte Schnittstellen gibt es auch zwei Möglichkeiten. Die Standardnotation ist analog zu der Realisierungsbeziehung (siehe Abbildung 6.25: Die Klasse fordert die Schnittstelle Person an.).

Abbildung 
  6.25: Die Klasse fordert die Schnittstelle Person an.

Auch hierfür gibt es eine Kurznotation:

Abbildung 
  6.26: Die Klasse Mitarbeiter fordert die Schnittstelle Person an

Hierbei werden wiederum die enthaltenen Operationen und Attribute nicht angezeigt. Im Übrigen kann man auch beide Notationen mischen, dies stellt dann die Kombination von der Forderung und der Implementierung dar.

Abbildung 
  6.27: Mitarbeiter fordert die Implementierung des Interface Person, und Kunde 
  implementiert sie einfach

Generalisierung, Vererbung

Allgemein gesagt drückt die Generalisierung (Spezifikation: Generalization) eine Beziehung von einem allgemeinen Fall zu einem speziellen Fall der Klasse aus. Sie dient der Strukturierung von Aufgabengebieten einer Klasse. Die einzelnen Merkmale der Oberklasse werden durch die Generalisierung an die Elemente der Unterklasse weitergegeben.

Eine Frage, die sich natürlich stellt, ist: Warum setzt man die Generalisierung überhaupt ein? Kurz gefasst ist sie eben ein geeigneter Weg, um Coderedundanzen zu vermeiden. Es ist dabei wichtig, eine Oberklasse zu finden, die grundlegende Eigenschaften hat und diese weiter vererbt. Der Erbling erbt somit diese Eigenschaften und kann selbst noch zusätzliches definieren.

Wichtig zu bemerken ist, dass ein Objekt, das von einer Unterklasse instanziert wurde, jederzeit ein Objekt der Oberklasse ersetzen kann. Dies verbirgt sich in der Objektorientierung hinter dem Begriff des Substitutionsprinzips.

Die Generalisierung dürfte den allermeisten Programmierern wohl durch den Begriff »Vererbung« bekannt sein. Die Generalisierung wird dargestellt durch einen Pfeil mit einer dreieckigen Spitze, der nicht ausgefüllt ist.

Abbildung 
6.28: Klasse 1 erbt von Klasse 2

In der UML kann man das Überschreiben von Merkmalen (Spezifikation: ReDefinition) über die Metamodellklasse

RedefinableElement
steuern. In einer Generalisierungsbeziehung dürfen alle Metamodellelemente überschreiben, sofern sie eine Unterklasse von
RedefinableElement
sind. Die Überschreibung erfolgt z.B. bei einem Attribut über den Eigenschaftswert
{redefines}.

Mehrere Klassen können von einer Oberklasse erben. Daher ist der Begriff der Generalisierung auch sehr treffend, weil eben eine Oberklasse grundsätzliche Eigenschaften an eine Unterklasse weitergibt, die spezifischer wird.

Abbildung 6.29: Eine Oberklasse mit mehreren Unterklassen zeigt die Notation einer Oberklasse, von der mehrere Unterklassen erben.

Abbildung 
  6.29: Eine Oberklasse mit mehreren Unterklassen

Oftmals möchte man ausdrücken, welchen Grund eine Generalisierung hat. Abbildung 6.30: Notation für eine Generalisierungsmenge (GeneralizationSet) zeigt eine Generalisierung mit der so genannten Generalisierungsmenge (Spezifikation: GeneralizationSet).

Im Folgenden werden wir uns etwas genauer damit beschäftigen, was auch im Hinblick auf die Fundamental-Prüfung nicht schaden kann. Prüfungsthema ist dies allerdings erst in der Prüfung der Stufe Advanced.

Abbildung 
  6.30: Notation für eine Generalisierungsmenge (<em>GeneralizationSet</em>)

Auf der rechten Seite in der Abbildung wird aufgezeigt, dass vom allgemeinen Fall »Personal« Klassen abgebildet werden, die den Mitarbeiterstatus genauer spezifizieren und zusätzliche Merkmale zu den Klassen hinzufügen. Beispielsweise wird ein Chef bestimmte Dinge tun und erledigen können, wozu ein Angestellter oder Praktikant nicht berechtigt ist. Allen Unterklassen ist aber gemeinsam, dass eine Personalnummer vergeben werden muss, egal ob es sich um einen Praktikanten, einen Angestellten oder einen Chef handelt.

Die Generalisierungsmenge (Spezifikation: GeneralizationSet) benennt die Zusammensetzung der so genannten Generalisierungskanten. Die einzelnen Realisierungen bilden wiederum die so genannten Partitionen (Spezifikation: partitions). Weiterhin können die Generalisierungseigenschaften darunter in geschweiften Klammern angegeben werden, für die wiederum Schlüsselwörter angegeben werden müssen, die in nachfolgender Tabelle genauer erläutert werden.

Schlüsselwort Bedeutung
complete
Besagt, dass in dieser Menge alle in dem logischen Kontext vorkommenden Spezialisierungen vorhanden sind. Es gibt im logischen Zusammenhang bei dieser Notation keine anderen Abkömmlinge der Klasse
Person
, außer
Angestellter, Praktikant
und
Chef.
incomplete
Die vorhandenen Spezialisierungen sind noch nicht vollständig, es können also jederzeit weitere Klassen abgeleitet werden, die in diesen logischen Zusammenhang passen.
disjoint
Es kann immer nur eine Ausprägung innerhalb des Kontextes zu sich selbst konform sein. Dies bedeutet, dass ein Chef nicht gleichzeitig ein
Praktikant
oder ein
Angestellter
sein kann.
overlapping
Es sind hier im Gegensatz zu
disjoint
durchaus Objekte erlaubt, die sowohl von der einen Klasse als auch von der anderen Klasse stammen können.

Tabelle 4.6: Generalisierungsmenge

Assoziationen (Associations)

Die Assoziation (Spezifikation: associations) beschreibt grundsätzlich Beziehungen zwischen Klassen. Die Beziehung wird dabei genau beschrieben und benannt. Sie wird durch eine durchgezogene Linie zwischen Klassen dargestellt und kann einen Namen tragen. Inhaltlich kann die Beziehung dann durch natürliche Sprachelemente, aber auch durch grafische Notationen konkret beschrieben werden.

Zwischen den Linien, die die Assoziationen darstellen, kann eine gestrichelte Linie gezogen werden. Mit dieser Notation können weitere Einschränkungen notiert werden.

Nachfolgend zeigen wir auf, welche verschiedenen Ausprägungen auftreten können:

Im einfachsten Fall besteht die Assoziation aus einer durchgezogenen Linie zwischen zwei Klassen. An der Linie kann die jeweilige Rolle der Klasse notiert werden, die die genaue Verwendung der Klasse bezeichnet. Die

Person
ist also gemäß der nachfolgenden Abbildung in der Rolle des
Fahrers
im Kontext dieser Assoziation und das
Auto
wird von dem
Fahrer
gefahren. Bei dem Klassennamen ändert sich in diesem Zusammenhang nichts, die Rolle beschreibt lediglich die Klasse in dem Kontext der Assoziation, ähnlich wie ein Schauspieler eine Rolle spielt. Mit einer Rolle kann zudem eine Multiplizität angegeben werden. Wenn die Multiziplität nicht angegeben wird, ist 0..* voreingestellt. Die Assoziation enthält zudem einen Namen, dessen Bezeichnung mittig an die Linie angebracht wird.

Wichtig hierbei ist zu erwähnen, dass auch zwei Assoziationslinien gezogen werden können, in der andere Rollen eingenommen werden. Zum Beispiel könnte die

Person
das Auto verleihen, in dem Fall wäre die
Person
nicht der
Fahrer,
sondern der
Verleiher
des Autos. Eine Rolle besagt nichts anderes als eine Eigenschaft (Property). Im folgenden Beispiel ist eine
Person
in die Rolle des
Fahrers
gelangt. Die Rollenangaben können hier wiederum ebenfalls eine Sichtbarkeit enthalten und im nachfolgenden Beispiel ist diese Sichtbarkeit in beiden Fällen
public.
Dies bedeutet, dass benachbarte Klassen Zugriff auf diese Operation des Objektes haben. In diesem Beispiel würde es Folgendes bedeuten: Ein Objekt mit dem Namen
Fahrer
der Klasse
Person
wird gebildet und kann dann dieses Auto fahren.

Abbildung 
  6.31: Einfache Assoziation mit Rollenangabe

Vor den Namen kann man einen Schrägstrich

(/)
setzen, also
(/Auto Fahren).
Dies bedeutet, dass diese Assoziation von einer anderen Assoziation abgeleitet ist.

Der Assoziation kann grundsätzlich auch mit einer so genannten Leserichtung versehen werden. Diese Leserichtung beschreibt die Beziehung zwischen den beiden Klassen näher.

Abbildung 
  6.32: Leserichtung einer Assoziation

Vom Prinzip besagt eine angegebene Leserichtung in etwa das, was auch eine Rollenangabe der Klasse innerhalb der Assoziation besagen würde. Allerdings ist die Rollenangabe weitaus aussagekräftiger als die Angabe der Leserichtung. Die Leserichtung sagt nur aus, dass die

Ehefrau
grundsätzlich die
Person
begleitet, während die
Person
und die
Ehefrau
für sich genommen keine Rolle haben.

Die Darstellungsweise in Abbildung 6.33: Angabe der Leserichtung mit einer Rolle ist nunmehr identisch mit der Angabe der Leserichtung.

Abbildung 
  6.33: Angabe der Leserichtung mit einer Rolle

Die Pfeilrichtung besagt, dass es sich um eine gerichtete Assoziation handelt. In diesem Fall heißt das, dass die

Person
in jedem Fall Kenntnis von der
Ehefrau
hat. Umgekehrt kann die
Ehefrau
von der
Person,
die sie geheiratet hat, Kenntnis haben, muss es aber nicht zwingend, weil der Pfeil auf die andere Richtung nicht existiert. Dies ist natürlich rein logisch unrealistisch. Wenn also beide zwingend voneinander Kenntnis haben müssen, dann sähe die Notation wie in Abbildung 6.34: Beide Klassen haben zwingend Kenntnis voneinander aus:

Abbildung 
  6.34: Beide Klassen haben zwingend Kenntnis voneinander

Ein weiterer möglicher Fall ist, dass eine Klasse die andere Klasse kennen darf, oder sogar zwingend kennen muss, umgekehrt aber die gegenüberliegende Klasse die andere Klasse zwingend nicht kennen darf. Die Tatsache, dass eine Klasse die andere Klasse nicht kennen darf, wird mit einem Kreuz wie in Abbildung 6.35: Bankberater kennt zwingend den Kunden, aber nicht umgekehrt.deklariert:

Abbildung 
  6.35: Bankberater kennt zwingend den Kunden, aber nicht umgekehrt.

Man spricht an dieser Stelle auch von unidirektionaler und bidirektionaler Assoziation. Bidirektionale Assoziation bedeutet, dass in beide Richtungen navigiert werden kann, während unidirektional bedeutet, dass nur eine Richtung erlaubt ist.

Der Unterschied zwischen einer angegebenen Leserichtung und der gerichteten Assoziation ist, dass die Leserichtung lediglich zu einem besseren Verständnis für die Notation und den logischen Zusammenhang genutzt wird. Die gerichtete Assoziation hingegen bestimmt zwingend, ob ein Objekt auf ein anderes zugreifen darf.

n-äre Assoziation

Es gibt neben der gewöhnlichen Assoziation auch den Fall, dass mehr als zwei Assoziationsenden verfügbar sein müssen. Dies nennt man in der UML mehrgliedrige Assoziation. Dabei gibt es keine Möglichkeit, die n-äre Assoziation zu benennen, zumal aufgrund der Anordnung des Notationselementes kein Platz dafür vorhanden ist.

Abbildung 
  6.36: n-äre Assoziation

Natürlich können hier auch wiederum Multiplizitäten angegeben werden. Allerdings ist im Zusammenhang der n-ären Assoziation weder eine Aggregation noch eine Komposition erlaubt.

Vererbung von Assoziationen

Assoziationen können jederzeit generalisiert werden. Sie sind spezielle Classifier, somit steht ihnen quasi diese Möglichkeit offen. Es gibt einige formelle Regeln, an die es sich dabei zu halten gilt. Somit muss zum Beispiel die Anzahl der Assoziationsenden gleich bleiben und die beteiligten Klassen müssen gleich sein und entsprechend ebenfalls in einem Generalisierungszusammenhang stehen. Des Weiteren darf die Multiplizität der Assoziation bei dem Erbling nicht erweitert werden. Sie darf allerdings explizit eingeschränkt werden.

In Abbildung 6.37: Generalisierung von Assoziationen sehen Sie eine Anwendung der Assoziationsvererbung. In dem Fall erbt die untere Assoziation von der oberen und die unteren beiden Klassen erben alle Eigenschaften der oberen Assoziation. An dieser Stelle kann ein Generalisierungspfeil zusätzlich von der oberen Assoziationslinie zur unteren gezogen werden.

Aggregation

Bei der Aggregation handelt es sich um eine so genannte Teile-Ganzes-Beziehung. Sie ist im Grunde genommen ebenfalls eine Aggregation, die eine Beziehung darstellt, allerdings mit der Prämisse, dass sie nicht ganz gleichberechtigt ist. In der UML-2.0-Spezifikation der OMG übersetzt man die Aggregation mit »besteht aus«. Das Ende mit der leeren Raute bezeichnet die Klasse, die das Ganze darstellt. Das gegenüberliegende Assoziationsende ist ein Teil, das zum Ganzen gehört. Die Notation sieht wie in Abbildung aus.

Abbildung 
  6.38: Aggregation</p>

In diesem Fall besteht ein Flugzeug aus mindestens einem Motor und maximal zwei Motoren, was die Multiziplität an den Aggregationsenden aussagt. Grundsätzlich könnte man auch eine Assoziationsbeziehung benutzen, um das Gleiche auszudrücken. Hier würde Flugzeug eine Rolle »besteht aus« zugewiesen und der

Motor
eben die Rolle »ist Teil von« zugewiesen bekommen. Am Assoziationsende des Ganzen ist eine Navigierbarkeit nicht möglich. Natürlich kann man die Notation mit einer Leserichtung versehen und Ähnliches.

Die Lebensdauer des Ganzen überdauert die Lebensdauer der Teile und umgekehrt. Die Teile des Ganzen können sogar grundsätzlich auch für andere Klassen Teile sein. Die Multiziplitäten modellieren bei der Aggregation die Anzahl der Teile in einem Ganzen und in wie vielen Ganzen die einzelnen Teile vorhanden seien dürfen.

Komposition

Die Komposition stellt in diesem Zusammenhang eine weitaus strengere Form der Aggregation dar, bei der die Teile vom Ganzen sogar existenzabhängig sind. Es ist an dieser Stelle eine so genannte Inklusion der Teile zu einem Ganzen. In diesem Fall stellen Teile und das Ganze eine Einheit dar. Somit kann die Zerstörung dieser Einheit oder Teile daraus die Zerstörung des Ganzen zur Folge haben. Die Notation sieht wie in Abbildung 6.39: Komposition aus:

Abbildung 
  6.39: Komposition

Die vorherige Abbildung besagt genau, dass ein Flugzeug kein oder ein Motor enthalten darf. Erst durch die Motoren wird das Flugzeug zu einem Ganzen. Hier wären also Segelflugzeuge sicherlich auch berücksichtig, denn Sie hätten dann kein Motor. Bei der Komposition ist die Auswahl der Multiziplitäten, die verwendet werden dürfen, beschränkt. Während ein Ganzes aus diversen Teilen bestehen kann, darf ein Teil nur zu genau einem Ganzen gehören. Es darf nicht zusätzlich noch zu einem anderen Ganzen gehören. Die Notation für die Multiziplität an der Raute kann weggelassen werden, da sie damit grundsätzlich 1 ist.

Pakete und Namensräume

Bei der Klasse haben Sie schon einmal das so genannte benennbare Element (NamedElement) kennen gelernt. In der UML 2.0 handelt es sich dabei um ein Element, das einen Namen und eine direkte Sichtbarkeit haben muss, die frei vorgebbar sind.

In einem so genannten Namensraum (Namespace) können benennbare Elemente eingefügt werden. Wichtig ist, dass sie innerhalb des Namensraumes, der zum Beispiel eine große Ansammlung von Elementen genauer gliedert, eindeutig sind. Von außen kann man das Element mit dem qualifizierten Namen ansprechen. Da Namensräume ineinander verschachtelt sein können, können die qualifizierten Namen sehr ausschweifend werden und somit über mehrere Namensräume gehen. Die entsprechende Notation ist folgendermaßen:

Namensraum1::Namensraum2::Klasse1

Zur besseren Strukturierung werden Klassen in so genannte Pakete gegliedert, die mit den Namensräumen zusammenhängen. Elemente, die in Paketen gegliedert werden dürfen sind die so genannten Paket-Elemente (PackageableElement). Dieses Konzept findet sich in vielen Programmiersprachen wieder, natürlich auch in Java und C#. Die UML 2.0 enthält eine Diagrammart, in der Pakete ausgedrückt werden. Damit kann man mehrere Classifier immer zu einem Paket zusammenfassen und erhält somit eine abstrakte Übersicht über verschiedene Funktionalitäten. Die einzelnen Pakete können beliebige Typen enthalten. Jedes Paket enthält einen Namensraum, in dem die Namen der Classifier eindeutig sein müssen. Jedes in einem Paket enthaltene Element kann über einen qualifizierten Namen

(Paketname::Klassenname)
angesprochen werden, innerhalb eines Paketes auch über einen unqualifizierten Namen. Dabei besteht der unqualifizierte Name nur aus dem Namen des Classifiers. Innerhalb eines Paketes kommt man in jedem Falle an einen anderen Classifier heran, außerhalb des Paketes kommt man ebenfalls unqualifiziert an die einzelnen Classifier heran, es hängt allerdings davon ab, wie die einzelnen Classifier zugreifbar sind. Hier gilt wiederum für
private
das Minuszeichen (-). Damit darf von außen nicht auf das Element zugegriffen werden. Für
public
gilt dementsprechend das Pluszeichen (+), das besagt, dass von jeder Stelle des gesamten Modells auf dieses Element mit dem qualifizierten Namen zugegriffen werden darf. Die Pakete können wiederum selbst Pakete enthalten, wodurch sie hierarchisch gegliedert sind. Je nach Detaillierungsgrad kann man so die genaue Klassenanordnung einmal weglassen und das Gesamtsystem verdeutlichen und die Wiederverwendbarkeit übersichtlich darstellen. Ist ein Programmteil fertig, der auch für andere neu zu erstellende Programme nutzbar ist, kann man sich die vorhandene Programmlogik abstrakt verdeutlichen und im Zusammenhang mit der neu zu programmierenden Logik darstellen.

Abbildung 
  6.40: Paketdiagramm

Abbildung 6.40: Paketdiagramm zeigt ein Paket mit zwei Klassen. Eine davon ist als

private
deklariert, die andere ist
public.

Auch bei einer Verschachtelung von Paketen kann die vorherige Notation übernommen werden. Hierbei können statt der Klassen jeweils die Pakete notiert werden.

Ein Paket kann importiert werden, was sich durch einen gestrichelten Pfeil zwischen zwei Paketen darstellen lässt, an dem ein Stereotyp mit dem Schlüsselwort

<<import>>
angebracht ist. Es besagt, dass der Import
public
ist. Im Gegensatz dazu gibt es auch einen Import, der
private
ist. Dieser ist identisch, nur das Schlüsselwort lautet nunmehr
<<access>>.

Abbildung 
  6.41: Der Paketimport

Vom

Paket_2
kann nunmehr die
Klasse_4
direkt angesprochen werden. Zudem kann von außen aus direkt ebenfalls über das
Paket_2
auf
Klasse_4
im
Paket_4
zugegriffen werden. Der Grund ist der
<<import>>.
Somit kann von
Paket_2
aus auf die
Klasse_4,
enthalten im
Paket_4,
direkt zugegriffen werden. Anders sieht es beim
<<access>>
aus. Hier kann zwar von
Paket_2
direkt auf die
Klasse_1
zugegriffen werden, die im
Paket_1
enthalten ist, allerdings geht das von außen über das
Paket_2
nicht. Somit kann aus dem
Paket_3
aus nicht auf die
Klasse_1
zugegriffen werden, weil
Paket_2
nur einen &
<<access>>
-Import, also einen privaten Import auf
Paket_1
hat.

Es gibt darüber hinaus eine verkürzte Notation für den Import, das so genannte Paket-Merge. Hierbei wird der Zugriff mit

<<merge>>
notiert und beinhaltet eine Verschmelzung des Pakets, das auf diese Weise importiert wird. Vom Prinzip her spricht man an dieser Stelle von einer Generalisierung.

Abbildung 
  6.42: Darstellung einer Merge-Beziehung

Abbildung 6.42: Darstellung einer Merge-Beziehung zeigt den

<<merge>>
-Import, der besagt, dass die
Klasse 2
im Paket 1 genauso angesprochen werden kann, als wäre diese direkt in
Paket 1
selbst vorhanden. An dieser Stelle spricht man beim
<<merge>>
-Import von einer Verschmelzung. Wichtig zu erwähnen ist, dass private Elemente nicht einbezogen werden. Formal kann man diese Verschmelzung gemäß der Spezifikation auch durch eine Generalisierung darstellen:

Abbildung 
  6.43: Darstellung des Merge zwischen den beiden Paketen mit der Generalisierung

Wie Sie in Abbildung 6.43: Darstellung des Merge zwischen den beiden Paketen mit der Generalisierung erkennen, kann man innerhalb von

Paket 1
auch auf die
Klasse 2
direkt zugreifen, ohne den qualifizierten Namen
Paket 2::Klasse 2
zu benutzen. Es stellt sich nunmehr die Frage, was passiert, wenn in Paket 2 bereits eine eigene
Klasse 2
vorhanden gewesen wäre und man zusätzlich aus
Paket 2
eine andere
Klasse 2
mit dem gleichen Namen als Merge importiert. Die Antwort ist: Es entsteht eine komplett zusammengefasste neue
Klasse 2
mit allen Membern (Attributen und Operationen) der beiden Klassen.

Zusammenfassend ist zu sagen, dass beim Import eines einzelnen Elements dieses Element per unqualifiziertem Namen angesprochen werden kann. Hierbei kann auch ein Aliasname verwendet werden. Ein Aliasname kann hingegen nicht verwendet werden, wenn ein komplettes Paket mit mehreren Elementen importiert wird.

Ein Paket ist immer auch ein Namensraum, (Spezifikation: Namespace), das benennbare Elemente (NamedElement) beinhalten kann. In dem Namensraum selbst müssen diese Elemente eindeutig identifizierbar sein. Außerhalb dieses Namensraumes kann ein Element mit gleichen Namen existieren. Mit den so genannten qualifizierten Namen können diese Elemente direkt identifiziert werden.

    Comelio GmbH UML Klassendiagramm UML Unified Diagramme Modeling Anleitung Handbuch Notation Language Manual Hamburg Stuttgart Bonn Leipzig Ingolstadt Ol Hannover Freiburg Zwickau Würzuburg Köln Magdeburg Heidelberg Wolfsburg Mannheim Göttingen Koblenz Bremen Kiel Lübeck Rügen Andernach Koblenz Frankfurt Berlin Erlangen Kassel Aachen München Ludwigshafen BochumComelio GmbH UML Klassendiagramm UML Unified Diagramme Modeling Anleitung Handbuch Notation Language Manual Hamburg Stuttgart Bonn Leipzig Ingolstadt Ol Hannover Freiburg Zwickau Würzuburg Köln Magdeburg Heidelberg Wolfsburg Mannheim Göttingen Koblenz Bremen Kiel Lübeck Rügen Andernach Koblenz Frankfurt Berlin Erlangen Kassel Aachen München Ludwigshafen BochumComelio GmbH UML Klassendiagramm UML Unified Diagramme Modeling Anleitung Handbuch Notation Language Manual Hamburg Stuttgart Bonn Leipzig Ingolstadt Ol Hannover Freiburg Zwickau Würzuburg Köln Magdeburg Heidelberg Wolfsburg Mannheim Göttingen Koblenz Bremen Kiel Lübeck Rügen Andernach Koblenz Frankfurt Berlin Erlangen Kassel Aachen München Ludwigshafen BochumComelio GmbH UML Klassendiagramm UML Unified Diagramme Modeling Anleitung Handbuch Notation Language Manual Hamburg Stuttgart Bonn Leipzig Ingolstadt Ol Hannover Freiburg Zwickau Würzuburg Köln Magdeburg Heidelberg Wolfsburg Mannheim Göttingen Koblenz Bremen Kiel Lübeck Rügen Andernach Koblenz Frankfurt Berlin Erlangen Kassel Aachen München Ludwigshafen BochumComelio GmbH UML Klassendiagramm UML Unified Diagramme Modeling Anleitung Handbuch Notation Language Manual Hamburg Stuttgart Bonn Leipzig Ingolstadt Ol Hannover Freiburg Zwickau Würzuburg Köln Magdeburg Heidelberg Wolfsburg Mannheim Göttingen Koblenz Bremen Kiel Lübeck Rügen Andernach Koblenz Frankfurt Berlin Erlangen Kassel Aachen München Ludwigshafen BochumComelio GmbH UML Klassendiagramm UML Unified Diagramme Modeling Anleitung Handbuch Notation Language Manual Hamburg Stuttgart Bonn Leipzig Ingolstadt Ol Hannover Freiburg Zwickau Würzuburg Köln Magdeburg Heidelberg Wolfsburg Mannheim Göttingen Koblenz Bremen Kiel Lübeck Rügen Andernach Koblenz Frankfurt Berlin Erlangen Kassel Aachen München Ludwigshafen BochumComelio GmbH UML Klassendiagramm UML Unified Diagramme Modeling Anleitung Handbuch Notation Language Manual Hamburg Stuttgart Bonn Leipzig Ingolstadt Ol Hannover Freiburg Zwickau Würzuburg Köln Magdeburg Heidelberg Wolfsburg Mannheim Göttingen Koblenz Bremen Kiel Lübeck Rügen Andernach Koblenz Frankfurt Berlin Erlangen Kassel Aachen München Ludwigshafen BochumComelio GmbH UML Klassendiagramm UML Unified Diagramme Modeling Anleitung Handbuch Notation Language Manual Hamburg Stuttgart Bonn Leipzig Ingolstadt Ol Hannover Freiburg Zwickau Würzuburg Köln Magdeburg Heidelberg Wolfsburg Mannheim Göttingen Koblenz Bremen Kiel Lübeck Rügen Andernach Koblenz Frankfurt Berlin Erlangen Kassel Aachen München Ludwigshafen BochumComelio GmbH UML Klassendiagramm UML Unified Diagramme Modeling Anleitung Handbuch Notation Language Manual Hamburg Stuttgart Bonn Leipzig Ingolstadt Ol Hannover Freiburg Zwickau Würzuburg Köln Magdeburg Heidelberg Wolfsburg Mannheim Göttingen Koblenz Bremen Kiel Lübeck Rügen Andernach Koblenz Frankfurt Berlin Erlangen Kassel Aachen München Ludwigshafen Bochum
Seminare