Klassenschema
Inhaltsverzeichnis
1 Definition (von W. Kowarschick)[1]
Ein Klassenschema definiert die Schnittstelle, die alle Objekte der zugehörigen Klasse mindestens unterstützen müssen.
Das Klassenschema umfasst eine (endliche) Menge von Integritätsbedingungen, die alle zugehörigen Objekte (d.h. alle in der Extension der zugehörigen Klasse enthaltenen Elemente) zu jedem Zeitpunkt erfüllen müssen. Das Schema deklariert insbesondere die Methoden, die für jedes Objekt der Klassenextension jederzeit als Kommunikationsschnittstelle zur Verfügungstehen müssen.
2 Bemerkungen
Ein Klassenschema ist laut Definition nichts weiter als eine Menge von Integritätsbedingungen, die jedes Objekt erfüllen muss, dass der zugehörigen Klasse angehört.
Es gibt eine ganze Reihe von Integritätsbedingungen, die ein Klassenschema enthalten kann. Die wichtigsten sind:
2.1 Methoden-Signaturen
Eine Methoden-Signatur ist eine spezielle Integritätsbedingung, bestehend aus Zugriffsbeschränkungen (public, private, protected, internal etc.), Methodennamen, Eingabeparametern samt zugehörigen Datentypen sowie den Datentypen der Methodenergebnisse.
Das Vorhandensein einer Methoden-Signatur in einem Klassenschema definiert eine Invariante: Eine Methode, die dieser Signatur genügt, muss dauerhaft zur Kommunikation mit den Objekten der Klasse, die gemäß der Zugriffsbeschränkung Zugriff haben, zur Verfügung stehen.
Außerdem definiert jede Signatur eine Vorbedingung (zum Zeitpunkt des Methodenaufrufes müssen die Argumente den Bedingungen genügen, die in der Signatur an die Eingabeparameter gestellt werden) und eine Nachbedingung (die Methodernergebnisse genügen den in der Signatur geforderten Ergebnisdatentypen).
2.1.1 Beispiel
public class Person
{
private var v_birthday: Date;
// Method "age"
public function age(p_date: Date = null): int
{
if (p_date == null)
p_date = new Date();
return ( (v_birthday.month > p_date.month)
|| ((v_birthday.month = p_date.month) &&
(v_birthday.date > p_date.date)
)
)
? p_date.fullYear - v_birthday.fullYear - 1
: p_date.fullYear - v_birthday.fullYear
}
// Constructor
public function Person(p_birthday: Date)
{
v_birthday = p_birthday;
}
}
Jedes Personenobjekt, d.h. jedes Element der Extension der Klasse Person
stellt eine Methode age
zur Verfügung,
public function age(p_date: Date = null): int
auf die jedes (public
) andere Objekt zugreifen darf:
var wolfgang: Person = new Person(new Date(1961, 5, 5));
trace(wolfgang.age());
trace(wolfgang.age(new Date(2011,5,2)));
trace(wolfgang.age(new Date(2011,5,11)));
trace(wolfgang.age('2011-05-11')); // Fehler (zur Compilezeit),
// da die Vorbedingung
// „das Argument ist vom Typ Date“
// nicht erfüllt ist.
Der Eingabeparameter muss nicht angegeben werden (Defaultwert null
), aber
falls er angegeben wird, muss er vom Typ Date
sein (Vorbedingung).
Die Methode age
liefert eine Integerzahl zurück (Nachbedingung).
Dass age
(als Nachbedingung!) das Alter der aktuellen Person zu einem bestimmten Datum bzw. zum
aktuellen Datum (falls p_date == null
) ermittelt, lässt sich der Signatur dagegen nicht entnehmen.
Hierfür wäre die Angabe von weiteren Integritätsbedingungen notwendig, was aber nur von wenigen Sprachen, wie z.B. Eiffel,
unterstützt wird. Eine weitere (deutlich schwächere) Nachbedingung wäre z.B., dass das Resultat positiv sein muss,
wenn das übergebene Datum p_date
größer ist, als das Geburtsdatum. Diese Bedingung wird z.B. verletzt,
wenn p_date
so groß gewählt wird, dass das Alter größer ist als die größte darstellbare Integerzahl.
Um gerade vor solchen Überraschungen gefeit zu sein, ist der Einsatz von Integritätsüberprüfungen,
die über die Angabe von Signatur-Informationen hinaus gehen, sehr empfehlenswert.
Bislang wurde gezeigt, dass die Signatur der Methode age
eine Vor- und eine Nachbedingung formuliert.
Sie formuliert allerdings auch eine Invariante: Die Methode age
existiert dauerhaft, d.h. sie kann nicht
entfernt oder verändert werden:
wolfgang.age = null; // Fehler (zur Compilezeit)
Dies ist nicht so selbstverständlich, wie es zunächst scheint. Wäre (in ActionScript) die Klasse Person als dynamisch deklariert worden
public dynamic class Person
{
...
}
so könnten jedem Personenobjekt jederzeit neue Methoden zugefügt werden. Und diese können auch wieder entfernt werden:
wolfgang.ageChristmas2011 = function (): int { return wolfgang.age(new Date(2011,12,24)); };
trace(wolfgang.ageChristmas2011());
wolfgang.age = null; // immer noch ein Fehler (zur Compilezeit)
wolfgang.ageChristmas2011 = null; // kein Fehler
trace(wolfgang.ageChristmas2011()); // jetzt ein Fehler (zur Laufzeit),
// ageChristmas2011 existiert nicht mehr
2.2 Attribute
Attribute, wie z.B. birthday
, werden im Prinzip durch zwei Methoden definiert, eine
Getter-Methode zum Lesen des Attributwertes:
public function get birthday(): Date
und eine Setter-Methode zum Modifizieren des Attributwertes:
public function set birthday(p_birthday: Date): void
Bei Read-only-Attributen fehlt die Setter-Methode und bei Add-only-Attributen fehlt die Getter-Methode. Im Falle des Geburtstages ist es z.B. sinnvoll, das Geburtsdatum nur beim Erzeugen des Objektes mit Hilfe des Konstruktors zu initialisieren und daher auf eine Setter-MEthode zu Verzichten.
Fazit: Attribute werden auch durch spezielle Attribut-Signaturen, d.h. durch spezielle Integritätsbedingungen im Klassenschema deklariert.
2.3 Zustandsvariablen
Die Deklaration von Zustandsvariablen kann ebenfalls als Integritätsbedingung aufgefasst werden:
public birthday: Date;
legt beispielsweise fest, dass jedes (public
) Objekt jederzeit lesend und schreibend auf die Variable birthday
zugreifen darf. Dabei muss sie allerdings beachten, dass in dieser Zustandsvariablen nur Werte vom Typ Date
abgelegt werden dürfen.
2.3.1 Anmerkung
In Sprachen wie Java, die kein Attribute unterstützen werden öffentlich zugängliche Zustandsvariablen häufig als Attribute missbraucht.
Allerdings solle man in derartigen Sprachen besser Methoden wie getBirthday
und setBirthday
zur Simulation von Methoden verwenden.
2.4 Zustandsbeschränkungen
TBD
2.5 Beziehungsbeschränkungen
TBD
3 Quellen
- Kowarschick, W.: Multimedia-Programmierung
- Kowarschick, W. (2002): Multimedia-Programmierung - Objektorientierte Grundlagen