\chapter{TooL: Eine objektorientierte Variante von TL}\label{TooLSprach}Dieses
Kapitel beschreibt die zur Implementierung der im Rahmen dieser Arbeit
entwickelten Beh"alterklassenbibliothek verwendete Programmiersprache TooL
\cite{GaMa95a,GawMat96}. Sie wurde zur besseren Unterst"utzung
objektorientierter Programmierung im Tycoon-System entwickelt.

TooL ist eine objektorientierte Variante der Tycoon Language (TL) und
"ubernimmt einige wesentliche Eigenschaften dieser Sprache. So ist TooL wie
auch TL eine strikt typisierte Programmiersprache, die die Einhaltung der
Regeln 
ihres Typsystems durch statische Programmanalyse "uberpr"uft. Weiterhin hat man
auch in TooL die M"oglichkeit zur polymorphen 
Programmierung durch Verwendung von Typparametern f"ur Methoden und
Klassen. Typparameter f"ur Methoden ersetzen dabei in gewisser Weise die in TL
vorhandenen Typoperatoren. Im Gegensatz zu vielen anderen objektorientierten
Sprachen "ubernimmt TooL von TL auch die Funktionen h"oherer Ordnung. Dar"uber
hinaus wird aber in TooL ein streng objektorientierter Ansatz verfolgt. Alle
Sprachkomponenten werden als Objekte betrachtet, denen man Botschaften senden
kann. Auch Kontrollstrukturen werden auf diese Weise modelliert. So ist {\sf
while} eine Nachricht, die jedes Objekt versteht und die mit Hilfe von
Funktionsparametern zur Definition der Abbruchbedingung und des
Schleifenrumpfes die erwartete Berechnung ausl"ost.

\begin{figure}[htp]
\begin{xple}
\k{class} Object
\ldots
while(cond :\k{Fun}():Bool, statement :\k{Fun}():\k{Void}) :\k{Void}
  \k{\{}
  cond$[]$ $?$ \k{\{}statement$[]$, while(cond, statement)\k{\}}
  \k{\}}
\ldots
\end{xple}
\caption{Kontrollstrukturen als Botschaften}\label{KoStNa}
\end{figure}

Wie in Abbildung \ref{KoStNa} zu sehen, wird die Methode {\sf while} in der
Klasse {\sf Object}
definiert. Sie ruft sich rekursiv auf, solange die als Parameter
"ubergebene Funktion {\sf cond} den Wahrheiswert {\sf true} liefert. Vor jedem
weiteren Aufruf wird die f"ur den Schleifenrumpf stehende Funktion {\sf
statement} ausgef"uhrt.  

Die M"oglichkeiten zur Datenabstraktion werden in TooL auf die in der
Klassendefinition m"ogliche Aggregation von Methoden und Variablen
(Slots) 
vereinfacht, was der Abstraktion, wie sie durch {\em records} m"oglich ist,
entspricht. Die weiteren speziellen Eigenschaften von TooL werden nun in den
folgenden Abschnitten erl"autert.

     \section{Kapselung}
Das Prinzip der Kapselung als Hilfsmittel zur Festlegung einer definierten
Objektschnittstelle wird in TooL durch die M"oglichkeit unterst"utzt, die
Klassendefinition in einen "offentlichen und einen privaten Teil aufzuteilen.
Die Teilung wird, wie in Abbildung \ref{Kapsel} zu sehen, durch die
Schl"usselworte {\bf 
public} und {\bf private} symbolisiert. Zur Abgrenzung von Methoden und
Variablen wird zus"atzlich noch das Schl"usselwort {\bf methods} benutzt. Die
Variablen finden sich 
jeweils direkt hinter dem den Status beschreibenden Schl"usselwort.
F"ur den Benutzer eines Objektes sind dann nur die Methoden oder Variablen
zugreifbar, die in
der zugeh"origen Klasse als "offentlich ausgezeichnet wurden. Die textuelle
Trennung von Methodensignatur und Implementierung der Methode wird dadurch
nicht geleistet.

F"ur den Erben einer Klasse bedeutet die
Unterscheidung von "offentlichen und Privaten Definitionen keine
Zugriffsbeschr"ankung. Er kann auch auf die geerbten 
privaten Methoden zur"uckgreifen. Allerdings hat der Erbe keine M"oglichkeit
den 
Status, der durch die Erbschaft erhaltenen Methoden, zu "andern. Der Erbe mu"s
also die Schnittstelle des Erblassers "ubernehmen. Die Erlaubnis zur
Schnittstellenerweiterung besteht und unter Einhaltung der
Subtypbeziehung zum Erblasser sind auch Signaturver"anderungen m"oglich.

\begin{figure}[htp]
\begin{xple}
\k{class} Counted(E $<\!\!\!*\!\!:$ Equality)
\ldots
\k{public} \k{methods}
size :Int
  \k{\{}elementCount\k{\}}
\k{private}
  \k{}elementCount :Int
\k{methods}
;  
\end{xple}
\caption{Kapselung}\label{Kapsel}
\end{figure}

     \section{Mehrfachvererbung}
TooL bietet dem Programmierer Mehrfachvererbung an. Diese kann vom
Subklassenentwerfer genutzt werden, um die durch die Strukturierung
aufgeteilten Protokollbl"ocke 
je  nach Bedarf wieder zusammenzuf"uhren. Mit Hilfe des Schl"usselwortes {\bf
super} kann die Liste der Vorfahren einer Klasse definiert werden (Abbildung \ref{MeVe}).

\begin{figure}[htp]
\begin{xple}
\k{class} Indexed(E $<\!\!\!*\!\!:$ Equality)
\k{super} Bounded(E), Keyed(Int, E), Sortable(E)
\ldots
;  
\end{xple}
\caption{Mehrfachvererbung}\label{MeVe}
\end{figure}

Probleme bei der Verwendung von \label{MehrfachVererbungAlgorithmus}
Mehrfachvererbung k"onnen durch Namenskonflikte entstehen. Diese treten
prinzipiell dadurch auf, da"s zwei direkte Vorfahren Methoden gleicher Signatur
vererben. Es mu"s dann entschieden werden, welche der geerbten
Implementierungen angesprochen werden soll.
TooL bietet keine
direkte M"oglichkeit, beide Methodenimplementierungen zu nutzen. In Eiffel ist
dies beispielsweise durch Umbenennung von Methoden erreichbar. Die
Namenskonflikte 
werden in TooL durch Erstellung einer Klassenpr"azedenzliste gel"ost. Dazu
werden die Klassen des betroffenen Ausschnitts des Vererbungsgraphen durch
topologische Sortierung sequentialisiert. Wird ein Methodenaufruf abgearbeitet,
so setzt sich die Klasse durch, welche in der Pr"azedenzliste am weitesten
vorne zu finden ist. Durch die Reihenfolge, in der die
Vorg"anger in der Liste der Oberklassen angegeben werden, ist das
Sortierungsergebnis beeinflussbar und somit die Entscheidung zugunsten der
einen oder der anderen Implementierung herbeizuf"uhren.

%%%%%%%%%Bild: Mehrfachvererbung CPL
\renewcommand{\epsfsize}[2]{0.789#1}
\begin{figure}[htp]
\begin{center}
\leavevmode
\epsfxsize=16cm
\epsfysize=7cm
\epsffile{../Bilder/bjoern/TooL.cpl.ps}
\end{center}
\caption{Klassenpr"azedenzliste (cpl)}\label{KlPrLi}
\end{figure}

Durch jede in der Liste der
Oberklassen angegebene Klasse wird ein Teilgraph des gesamten
Vererbungsgraphen selektiert, der alle "uber diese Klasse erreichbaren
Vorfahren umfa"st. Diese Teilgraphen werden zur Erstellung der 
Pr"azedenzliste der Reihe nach betrachtet, so da"s die Klassen, des durch die
erste Oberklasse selektierten Teilgraphen, im Prinzip auch die h"ohere
Priorit"at haben. Kommt es jedoch zu "Uberschneidungen mit anderen
Teilgraphen, so wird die betroffene, in beiden vorhandene Klasse erst nach den,
in dem anderen 
Teilgraphen vor ihr liegenden Klassen, ber"ucksichtigt.

In Abbildung
\ref{KlPrLi} wird der Vererbungsgraph f"ur eine Klasse {\sf E} skizziert und
die Pr"azedenzliste f"ur diese Klasse angegeben.
Die Klasse {\sf B} in der Liste der Oberklassen von {\sf E} selektierte den ersten
Teilgraphen. Die Sequenzialisierung ergibt aufgrund der Angaben in Klasse
{\sf B} die Reihenfolge {\sf B}, {\sf D}, {\sf C}. Der zweite Teilgraph
sequentialisiert sich zu {\sf A}, {\sf D}. In der Gesamtliste wird aufgrund
der "Uberschneidung in Klasse {\sf D} nur das zweite Auftreten von {\sf D}
ber"ucksichtigt. Ein Namenskonflikt zwischen den Klassen {\sf A} und {\sf B}
etwa bez"uglich einer Methode {\sf m1}, wie in Abbildung \ref{KlPrLi}
angedeutet, w"urde zugunsten von Klasse {\sf B} entschieden. Dies ist auch
direkt aus der Reihenfolge in der Liste der Oberklassen von {\sf E}
ersichtlich, da diese Klassen direkte Vorfahren von {\sf E} sind. Ein weiterer
Konflikt zwischen den Klassen {\sf D} und {\sf C}, die Methode {\sf m2}
betreffend f"uhrte zur Ber"ucksichtigung der Version von Klasse {\sf C} obwohl
diese Version in Klasse {\sf B} als der Klasse-{D}-Version nachrangig
eingestuft wurde. Die Reihenfolge der Oberklassen in Klasse {\sf E} dominiert
hier die Angaben in den Oberklassen.

Beim "Uberschreiben von Methoden kann man mit Hilfe des Schl"usselwortes {\bf super} in Verbindung mit
dem Methodennamen die Implementierung der Oberklasse ansprechen. Welche
Oberklasse gemeint ist, wird wiederum "uber die Pr"azedenzliste
entschieden. Dabei sind auch Ketten von {\bf super}-Aufrufen denkbar, wodurch
dann auch die "uberschriebenen Implementierungen, der in der
Pr"azedenzliste weiter hinten liegenden Klassen, erreichbar sind.

     \section{Metaklassen}Die streng objektorientierte Sichtweise von TooL
legt die Integration von Metaklassen in das Sprachkonzept
nahe \cite[S.14]{GaMa95a}. Auch Klassen
werden als Objekte betrachtet, denen man Botschaften senden kann. Die
Spezifikation der Botschaften die eine Klasse versteht, erfolgt in der
Metaklasse. Die Zuordnung einer Metaklasse zu einer Klasse ist nicht
automatisiert wie etwa in Smalltalk, sondern wird in TooL explizit
"uber das Schl"usselwort {\bf metaclass} gesteuert. Dadurch ist der Aufbau
einer unabh"angigen Metaklassenhierarchie m"oglich. In der Klassenbibliothek
von TooL werden die Metaklassen gegenw"artig zur Definition von Methoden zur
Objekterzeugung genutzt\footnote{Andere M"oglichkeiten f"ur den Einsatz von
Metaklassen werden mit weiteren Verweisen bei \cite[S.14]{GaMa95a}
genannt. Eine "Ubersicht auf die von verschiedenen Sprachen angebotenen
Meta-Konzepte findet sich in \cite{Sib95}}. 

\begin{figure}[htp]
\begin{xple}
\k{class} SetClass(E $<\!\!\!*\!\!:$ Equality, Instance $<\!\!\!*\!\!:$ Set(E))
\k{super} Class(Instance)
\k{public} \k{methods}

create(stream :FiniteReadStream(E)) :Instance
  \k{\{}
  let obj :Instance = new,
  stream.do(\k{fun}(e :E){obj.set(e)}),
  obj
  \k{\}}
;  
\end{xple}
\caption{Eine Metaklasse}\label{MetKl}
\end{figure}

Das durch eine Klasse spezifizierte Objekt mu"s erzeugt werden. Dies geschieht
in TooL nicht durch fest eingebaute Konstruktoren, sondern durch Senden
einer Erzeugungsnachricht an die Klasse des zu erzeugenden Objekts. Die
entsprechende Methode wird daher in der Metaklasse spezifiziert. Die
Typisierung der Objekterzeugungsmethode erfolgt durch 
Parametrisierung der Metaklasse mit dem Objekttyp.
Durch die Bekanntmachung des 
Objekttyps in der Metaklasse ist auch der Zugriff auf die Objektschnittstelle
der zugeordneten Klasse m"oglich, was sich bei der Implementierung von Methoden
ausnutzen l"a"st. So ist zum Beispiel die Erzeugung bereits gef"ullter
Beh"alter durch Verwendung von Einf"ugeprotokoll m"oglich.
Eine weitere Anwendung liegt in der Definition von Klassenkonstanten, die f"ur
alle Objekte der Klasse nur einmal formuliert zu werden brauchen.

Als Beispiel diene die Metaklasse {\sf SetClass} in Abbildung \ref{MetKl}. Sie
ben"otigt den 
zweiten Typparameter, da die Bindung f"ur den Objekttyp-Parameter {\sf
Instance} 
selbst ein Objekttyp mit Typparameter ist, welcher den Elementtyp der Liste
beschreibt. Sie erbt von der Metaklasse {\sf 
Class} welche die Methode {\sf new} definiert. {\sf Class} ist auch die
voreingestellte Metaklasse, die zugewiesen wird, wenn in der Klassendefinition
keine Angabe Metaklasse erfolgt ist. 

     \section{Abstrakte Klassen}Das Konzept der abstrakten Klasse
erm"oglicht die Spezifikation von abstraktem, (noch) nicht implementiertem
Protokoll 
in Form von Methodensignaturen.\footnote{In TooL ist auch die Formulierung von
Vor- und Nachbedingungen erlaubt. Siehe dazu auch Abschnitt
\ref{Smntkspzfktn}}. Abstrakte Klassen k"onnen au"serdem genutzt werden, um 
Protokoll bereits 
teilweise unter Bezugnahme auf nicht implementierte Basismethoden zu
implementieren und um es dann in Subklassen durch Implementierung der
Basismethoden 
individuell an die Bed"urfnisse oder die Repr"asentation der Subklasse
anzupassen.

\begin{figure}[htp]
\begin{xple}
\k{class} Finite(E $<\!\!\!*\!\!:$ Equality)
\k{super} Boxed(E)
\k{metaclass} AbstractClass
\k{public} \k{methods}

size :Int deferred

isEmpty :Bool
  \k{\{}
  size == 0
  \k{\}}
;  
\end{xple}
\caption{Abstrakte Klassen}\label{AbstrKl}
\end{figure}

In TooL wird die Zur"uckstellung der Methodenimplementierung durch
das Schl"usselwort {\bf deferred} gekennzeichnet, welches an Stelle des
Methodenrumpfes eingef"ugt wird. Weiterhin ist es "ublich, einer solchen
abstrakten Klasse die Metaklasse {\sf AbstractClass} zuzuordnen. Diese
spezifiziert im Gegensatz zur Metaklasse {\sf Class} keine {\sf
new}-Methode. Die so definierte abstrakte Klasse kann also kein Objekt des in
ihr beschriebenen Typs erzeugen.
     \section{Typisierung}\label{TooLTyp}TooL bleibt, wie schon erw"ahnt,
eine strikt und statisch 
typisierte Sprache entsprechend ihrer Vorg"angerin TL. Die Klassendefinition
impliziert die Deklaration des der Klasse zugeordneten Objekttyps. Dieser
ergibt sich aus den 
Signaturen der "offentlichen Methoden. Die M"oglichkeiten zu rekursiven
Deklarationen beschr"anken sich auf den Typbezeichner {\bf Self}, welcher den
Objekttyp der Klasse selbst beschreibt, und den Wertbezeichner {\bf self},
welcher innerhalb des Methodenrumpfes f"ur das rekursive Ansprechen des
Empf"angerobjektes zur Verf"ugung steht. Eine weitere M"oglichkeit zur
rekursiven 
Typdefinition bietet aber auch die Verwendung des Klassennamens selbst. Die
Unterschiede der beiden Varianten liegen in den M"oglichkeiten der
Subklassenbildung und der Beziehung zwischen den Typen der Sub- und der
Oberklasse. Dies soll im folgenden erl"autert werden.

Im Unterschied zu anderen statisch typisierten objektorientierten Sprachen
bietet TooL nicht nur eine Subtyprelation ($<:$) auf Objekttypen an, sondern
kombiniert diese mit einer weiteren Typrelation ($<\!\!\!*\!\!:$). Diese
"Ahnlichkeitsrelation (type matching relation)\footnote{Eingef"uhrt von
\cite{BlackHut90} und \cite{Bruce93}} erm"oglicht die typsichere 
Vererbung von bin"aren Methoden oder allgemeiner von solchen Methoden, die
Parameter vom Typ {\bf Self} haben. Derartigen Methoden
mu"s also ein Objekt "ubergeben werden, dessen Typ durch die Klasse, in der die
Methode definiert wurde, beschrieben ist. Die Vererbung solcher Methoden kann 
bei Verwendung der reinen Subtypbeziehung als Konsistenzbedingung f"ur die
Vererbung nicht erlaubt werden. Die 
Spezialisierung des Objekttyps beim gleichzeitigen Vorhandensein bin"arer
Methoden f"uhrt zur Verletzung der Subtypbeziehung aufgrund des
kontravarianten Auftretens des Objekttyps als Parametertyp einer solchen
Methode (siehe auch Abschnitt \ref{DynPara} und \cite[S.8]{GaMa95a}).

Die Verkn"upfung der
"Ahnlichkeitsrelation mit der Vererbungsbeziehung, das hei"st die Verwendung
dieser Relation als weitere Konsistenzbedingung f"ur die Beziehung der
Objekttypen von Sub- und Oberklasse, soll nun diese zus"atzliche M"oglichkeit
der Spezialisierung offenhalten. Eine informelle Definition der
"Ahnlichkeitsbeziehung lautet:

\begin{tabbing}
aaa\=\kill
\>A $<\!\!\!*\!\!:$ B {\em wenn f"ur jeden Typbezeichner} {\bf Self} {\em in} A \\
\>{\em ein korrespondierender Bezeichner} {\bf Self} {\em in} B {\em existiert}\\
\>{\em und unter der Annahme, da"s korrespondierende Typbezeichner} {\bf Self}\\ 
\>{\em den gleichen Typ bezeichnen,} A $<\!\!:$ B {\em folgt.}\\
\end{tabbing}

Mit korrespondierenden Bezeichnern sind solche Bezeichner gemeint, die in den
beiden beteiligten Typdefinitionen (Klassendefinitionen) an gleicher Stelle
auftauchen. Dies kann z.B. als Parametertyp gleichnamiger Methoden oder als Typ
gleichnamiger Variablen der Fall sein.

%%%%%%%%%Bild: Verlust der Subtypbeziehung
\renewcommand{\epsfsize}[2]{0.789#1}
\begin{figure}[htb]
\begin{center}
\leavevmode
\epsfxsize=16cm
\epsfysize=7cm
\epsffile{../Bilder/bjoern/TooL.match1.ps}
\end{center}
\caption{Verlust der Subtypbeziehung}\label{VerSub}
\end{figure}

Durch die Verkn"upfung der
"Ahnlichkeitsrelation mit der Vererbungsrelation und aus der Tatsache, da"s es
sich bei dieser Relation um eine 'bedingte' Subtypbeziehung handelt, folgt
unmittelbar, da"s es keine erzwungene Subtypbeziehung zwischen Sub- und
Oberklasse gibt. Vererbungshierarchie und Subtyphierarchie der
Objekttypen der beteiligten Klassen sind damit nicht mehr identisch.

%%%%%%%%%Bild: Verlust der "Ahnlichkeit
\renewcommand{\epsfsize}[2]{0.789#1}
\begin{figure}[htb]
\begin{center}
\leavevmode
\epsfysize=2cm
\epsffile{../Bilder/bjoern/TooL.match2.ps}
\end{center}
\caption{Verlust der "Ahnlichkeitsbeziehung}\label{VerAeh}
\end{figure}

In Abbildung \ref{VerSub} wird die enge Verbindung der "Ahnlichkeitsrelation
mit dem Typbezeichner {\bf Self} sowie die Bedeutung von Subtypbeziehung und
"Ahnlichkeitsrelation als Konsistenzbedingung f"ur die Vererbung noch einmal
verdeutlicht. Die unter a) dargestellte Vererbungssituation, behandelt den Fall
der Spezialisierung durch die Subklasse, wobei in der Oberklasse kein
Selbstbezug unter Verwendung des Typbezeichners {\bf Self} zu finden ist. Die
Klasse {\sf Stream} wird von {\sf ReadStream} durch Hinzuf"ugen einer weiteren
Methode spezialisiert. In dieser Situation sind die beteiligten Objekttypen in
beiden Relationen enthalten.
F"ur die Vererbung bedeutet dies: solange kein
Typbezeichner {\bf Self} benutzt wird, ist die Mitgliedschaft in der
Subtyprelation die einzige Konsistenzbedingung f"ur die Vererbung.

In Fall b)
handelt es sich ebenfalls um eine Spezialisierungssituation, nur wird in
diesem Fall der Typbezeichner {\bf Self} in der Oberklasse {\sf Equality} als
Parametertyp 
f"ur die Methode ''$=$'' benutzt. Die Klasse {\sf Container} erbt diese
Methode und f"uhrt gleichzeitig eine weitere Methode ein, sie spezialisiert
also.
Der Typbezeichner {\bf Self} bezeichnet nun in beiden Klassen
unterschiedliche Typen, n"amlich gerade den Objekttyp der Klasse {\sf Equality}
bzw. den spezialisierten Objekttyp von {\sf Container}. Daher wird die
Subtypbeziehung zwischen diesen Objekttypen durch die Parameterspezialisierung
(Kontravarianzregel) verhindert. Die "Ahnlichkeitsbeziehung jedoch ist
erf"ullt. Denn wenn die korrespondierenden Bezeichner {\bf Self} in den beiden
{\sf equal}-Methoden den gleichen Typ beschreiben w"urden, so w"are die
Subtypbeziehung erhalten geblieben. Laut Definition ist dies aber f"ur die
Mitgliedschaft in der "Ahnlichkeitsrelation ausreichend. Die Vererbung ist
daher korrekt durchgef"uhrt worden.

Es kann aber auch zum Verlust der "Ahnlichkeitsbeziehung
kommen, wie schon der zweite Satz der Definition vermuten l"a"st : \ldots
{\em korrespondierende Typbezeichner} {\bf Self} {\em m"ussen existieren}.
In Abbildung \ref{VerAeh} findet sich eine solche Situation. Die Klasse {\sf
AbstractPoint} "uberschreibt die {\sf equal}-Methode so, da"s sie nur
{\sf Equality}-Objekte vergleichen kann. Trotz eventuell weiterer
Spezialisierung durch {\sf AbstractPoint}
besteht hier eine Subtypbeziehung zwischen den Objekttypen der beiden
Klassen, da diese Spezialisierungen nicht mehr kontravariant sichtbar
werden. Die "Ahnlichkeitsbeziehung ist jedoch nicht erf"ullt, da es zu dem 
{\bf Self}-Parameter keinen korrespondierenden Bezeichner in {\sf
AbstractPoint} gibt.

%%%%%%%%%Bild: Umschalten auf Subtyp
\renewcommand{\epsfsize}[2]{0.789#1}
\begin{figure}[htb]
\begin{center}
\leavevmode
\epsfysize=6cm
\epsffile{../Bilder/bjoern/TooL.match3.ps}
\end{center}
\caption{R"uckgewinnung der Subtypbeziehung}\label{UmSub}
\vspace*{0.5cm}
\end{figure}

Das Umschalten von "Ahnlichkeit auf Subtypbeziehung in
der Vererbungshierarchie, welches hier noch direkt durch "Uberschreiben
durchgef"uhrt wurde, kann in TooL auch mit Hilfe eines speziellen Konstruktes
erfolgen, welches eine Subtypbeschr"ankung f"ur den Typ {\bf Self}
festlegt. Mit der Formulierung 
\begin{xple}
  \k{Self} $<:$ \k{class} AbstractPoint \ldots
\end{xple}
wird dem Typ"uberpr"ufungsalgorithmus mitgeteilt, da"s in allen Nachfolgern
der Klasse der Bezeichner {\bf Self} nicht mehr den Objekttyp der aktuellen
Klasse, sondern den der Wurzelklasse (hier {\sf AbstractPoint})
beschreibt. Eine 
diese Bedingung erf"ullende Nutzung der Vererbung wird dann unterhalb einer
so formulierten Klasse erzwungen.

Die Einf"uhrung des Konstruktes soll
die M"oglichkeit er"offnen auf einfache Weise den Weg zur"uck zu einer die
Subtypbeziehung einhaltenden Vererbungshierarchie zu gehen, trotz einer weiter
oben im Vererbungsgraphen erfolgten kontravarianten Spezialisierung.
In Abbildung \ref{UmSub} ist diese Situation skizziert. Die nun spezialisierende
Klasse {\sf Point} erf"ullt die "Ahnlichkeitsbeziehung zu {\sf Equality} und
nutzt die Subtypbeschr"ankung f"ur {\bf Self}, um unter sich eine
Punktehierarchie entstehen zu lassen, f"ur welche die M"oglichkeit zur
Subsumption unter dem Objekttyp der Wurzelklasse {\sf Point} besteht. Die
"Ahnlichkeitsbeziehung zu {\sf Point} geht aber verloren, da die Verwendung von
'{\bf Self} $<:$' in Klasse {\sf Point} so interpretiert wird, als
wenn in den Subklassen alle Typbezeichner {\bf Self} durch den Typ {\sf Point}
ersetzt w"urden \cite[S.13]{GawMat96}. 
     \section{Polymorphismus}TooL bietet wie TL den
Subtyppolymorphismus\footnote{siehe \cite{Car85} f"ur die Klassifizierung der
verschiedenen Arten von Polymorphismus}
an. Das 
hei"st Variablen und Parameter k"onnen statt mit Werten ihres Deklarationstyps
auch mit Werten eines Subtyps belegt werden. Weiterhin unterst"utzt TooL
(ebenfalls in Nachfolge von TL) den gebunden-parametrischen Polymorphismus in
Bezug auf die Subtyprelation.

\begin{figure}[htp]
\begin{xple}
\k{class} AbstractLinkedList(E $<:$ Object, L $<\!\!\!*\!\!:$ Link(E))
\k{super} AbstractList(E)
\k{metaclass} AbstractClass
\k{public} \k{methods}
item :E \k{\{}listStart.item\k{\}}
\ldots
\k{private}
listStart :L, listEnd:L  /ldots
;
\end{xple}
\caption{Parametrischer Polymorphismus}\label{ParaPol}
\end{figure}

Das bedeutet die M"oglichkeit Methoden und
Klassen durch Typparameter generisch zu halten, die aber nur Subtypen des
einschr"ankenden Typs als "Ubergabetyp zulassen. Orthogonal zu dieser
Variante des Polymorphismus erlaubt TooL mit der Einf"uhrung der
"Ahnlichkeitsrelation auch einen gebunden-parametrischen
Polymorphismus in Bezug auf diese Typrelation. Diese Variante des
Polymorphismus in TooL entspricht dem sogenannten 'f-bounded polymorphism'
\cite{AbCa95}. Durch diese Erg"anzung besteht die 
M"oglichkeit, generische Anwendungen auch f"ur Objekte zu programmieren, deren
Objekttypen nur in "Ahnlichkeitsbeziehung stehen, wodurch der Verlust der
Subsumptionsf"ahigkeit etwas relativiert wird. 
Als Beispiel diene die Klasse {\sf AbstractLinkedList} in Abbildung
\ref{ParaPol}, welche beide Varianten von Typparametern nutzt.

\section{Semantikspezifikation}\label{Smntkspzfktn}TooL unterst"utzt das
Prinzip des 'design by contract' \cite[S.23]{Mey94a}, indem es die M"oglichkeit
zur 
Formulierung von einfachen Vor- und Nachbedingungen sowie zur Definition von
Klasseninvarianten bietet. Die Bedingungen werden durch Angabe von 
'booleschen' Ausdr"ucken spezifiziert. Dabei kann man die Funktionalit"at der
Klasse {\sf 
Bool} nutzen und sich auf die in der Klasse bekannten Methoden beziehen. Eine
Unterscheidung des Zustands vor Ausf"uhrung einer Methode von dem danach wird
derzeit nicht unterst"utzt\footnote{In Eiffel ist dies etwa f"ur
Nachbedingungen mit Hilfe des Schl"usselwortes {\bf old} m"oglich:\newline
{\sf ensure index
= old index + 1}.}. Vor- und Nachbedingungen werden zwischen Methodensignatur
und Methodenrumpf mit
Hilfe der Schl"usselworte {\bf require} und {\bf ensure} plaziert, w"ahrend die
Klasseninvarianten zwischen der Metaklassenangabe und
dem Schl"usselwort {\bf public} angesiedelt sind.

\begin{figure}[htp]
\begin{xple}
\k{class} Bilinear(E $<\!\!\!*\!\!:$ Object)
\k{super} Linear(E)
\k{metaclass} AbstractClass
\k{invariant} (isEmpty $=>$ isOff)
\k{public} \k{methods} \ldots
gotoIndex(pos :Int) :\k{Void}
  \k{require} (pos $>=$ 0) $\&$ !isEmpty
  \k{ensure} isOff $\parallel$ (index $==$ pos) 
  \k{\{}\ldots\k{\}}
;
\end{xple}
\caption{Semantikspezifikation}\label{SemSpez}
\end{figure}

Eine Vererbung der Pr"adikate
erfolgt nicht und ist im allgemeinen auch nicht sinnvoll
\protect{\linebreak[4]\cite{Mey88}}. 
Ein Anwendungsfall f"ur die Definition einer
Vorbedingung ist 
beispielsweise die Festlegung eines g"ultigen Wertebereichs f"ur die
Methodenparameter. Durch die Spezialisierung in der Subklasse kann es
aber erw"unscht sein, den Bereich an g"ultigen Werten f"ur die
Methodenparameter zu erweitern. Wenn die Bereichsfestlegung aus der Oberklasse
"ubernommen w"urde, w"are dies nicht m"oglich.

Die Formulierung von Invarianten
f"ur Methoden beziehungsweise die "Uberpr"ufung weiterer berechnungsabh"angiger
Bedingungen ist mit Hilfe des Schl"usselwortes {\bf assert} an jeder Stelle
des Methodenrumpfes erlaubt. 
In Abbildung \ref{SemSpez} sind die verschiedenen Formen der
Semantikspezifikation noch einmal dargestellt. 



