• Keine Ergebnisse gefunden

Eine Schnittstelle (interface) legt die Menge von Signalen fest, über die mit einem Agenten oder über einen Kanal kommuniziert werden kann. Dies kann eine Teilmenge aller Signale sein, die der Agent senden und empfangen kann. Jede Agententypdefinition impliziert eine Schnitt-stellendefinition, die nämlich die Menge aller Signale umfasst, die an den Gates dieses Agenten ausgetauscht werden kann17.

In diesem Zusammenhang bezeichnet „Signal“ nicht nur die direkt deklarierten Signale, son-dern auch diejenigen, die aus der Deklaration von entfernten Prozeduren und Variablen im Rah-men des Transformationsprozesses entstehen. In der Schnittstellendefinition können dementsprechend im Allgemeinen nicht nur Signale, sondern auch Variablen und Prozeduren angegeben werden.

Schnittstellen stehen in einer Spezialisierungshierarchie. Abweichend von anderen Speziali-sierungen ist bei Schnittstellen Mehrfachvererbung möglich: Die Signalmenge einer Schnitt-stelle ergibt sich aus der Vereinigung der Signalmengen der BasisschnittSchnitt-stellen zuzüglich der direkt in der Schnittstelle aufgeführten Signale. Bei Vererbung von Agententypen entsteht die implizite Schnittstelle des spezialisierten Agenten aus der impliziten Schnittstelle des Basis-agenten, sowie aller Schnittstellen, die an Gates in Richtung zum Agenten aufgeführt sind.

Ein Signal kann in einer Schnittstelle definiert werden. Ist die Definition des Signals bereits woanders erfolgt, kann das Signal in der Schnittstelle referenziert werden.

Eine Schnittstellendefinition impliziert die Definition einer Pid-Sorte. Pid-Sorten sind Spe-zialisierungen der Sorte Pid, also der Sorte, deren Werte Referenzen auf Agenten sind. Während alle Referenzen auf Agenten Element der Sorte Pid sind, sind in einer Pid-Sorte, die einer Schnittstelle S entspricht, nur Referenzen auf Agenten enthalten, deren implizite Schnittstelle eine Spezialisierung von S ist. Damit wird in SDL typsichere Kommunikation möglich: Beim Senden eines Signals kann schon festgestellt werden, ob der empfangende Agent das Signal auch verarbeiten kann (wobei das Verwerfen des Signals in einem Zustand hier auch als Verar-beitung gilt).

Eine Schnittstellendefinition erfolgt durch die Regel <interface definition>:

<interface definition> ::

<package use clause>* [<virtuality>] <interface heading> [<interface specialization>]

<entity in interface>* <interface use list>

17. Tatsächlich impliziert eine Agentdefinition mehrere Schnittstellendefinitionen, nämlich je eine für die Zustandsmachine des Agenten, für den Typ des Agenten, und für den Agenten selbst.

Wie auch in Datentypdefinitionen kann eine Schnittstellendefinition mit einer Liste verwen-deter Pakete beginnen, optional gefolgt vom einem der Schlüsselwort virtual, redefined oder finalized. Die Angabe des Schlüsselworts abstract ist hier nicht erlaubt, da Schnittstellen so-wieso nicht instanziert werden können, sondern neue Werte immer nur durch Erzeugung von Agenten entstehen.

Der Namen der Schnittstelle, die formalen Kontextparameter und Einschränkungen der Re-definition virtueller Schnittstellen finden sich in der Regel für den Schnittstellenkopf (<inter-face heading>):

<interface heading> ::

<interface<name> <formal context parameter>* [<virtuality constraint>]

Auf die Angabe des Schnittstellenkopfs folgt optional die Festlegung von Basisschnittstel-len; dies ist in Abschnitt 6.3 erläutert. Darauf folgt die Definition von Elementen, die in der Schnittstellendefinition enthalten sind. Diese sind durch die Regel <entity in interface> festge-legt:

<entity in interface> =

<signal definition>

| <interface variable definition>

| <interface procedure definition>

| <exception definition>

Wie bereits erläutert, kann eine Schnittstellendefinition die Definition von Signalen, entfern-ten Variablen und entfernentfern-ten Prozeduren enthalentfern-ten. Zusätzlich ist die Definition von Ausnah-men erlaubt, die dann beispielsweise in der Definition entfernter Prozeduren verwendet werden können.

Soll auf bereits definierte Signale zurückgegriffen werden, erfolgt dies durch die Regel <in-terface use list>:

<interface use list> :: <signal list item>*

Die hier nicht angegebene Regel <signal list item> erlaubt den Verweis auf Signale, Signal-listen, Timer, entfernte Prozeduren, Schnittstellen und entfernte Variablen.

Die Definition von entfernten Variablen und Prozeduren erfolgt innerhalb von Schnittstellen syntaktisch etwas anders als außerhalb, da in der Schnittstelle das Schlüsselwort remote nicht erforderlich und deshalb nicht erlaubt worden ist:

<interface variable definition> :: <remote variable<name>+ <sort>

<interface procedure definition> :: <remote procedure<name> <procedure signature>

Beispiel 12. Die Schnittstelle, die der Abbildung der OMG-IDL-Schnittstelle CosNaming::NamingContextExt [OMG02b] folgt, wie sie in [Z.130] definiert ist, lautet in SDL

use CORBA;

interface NamingContextExt inherits NamingContext {

exception InvalidAddress;

resolve_str(Charstring) -> Object raises InvalidName;

to_name(Charstring) -> Name raises InvalidName;

to_string(Name) -> Charstring

raises InvalidName, InvalidAddress;

to_url(Name) -> Charstring

raises InvalidName, InvalidAddress;

}

6.3 Spezialisierung

Die Spezialisierung von Datentypen in SDL stellt wie die Spezialisierung von Agenten eine Vererbungsrelation dar. Der spezialisierte Typ verfügt über alle Eigenschaften (enthaltene Vari-ablen, Typen, Transitionen usw.) des Basistyps und kann zusätzlich weitere Eigenschaften de-finieren.

Die Spezialisierung von Typen impliziert nicht automatisch, dass der spezialisierte Typ po-lymorph im Sinne des Liskovschen Substitutionsprinzips [Z.100-00] verwendet werden kann.

Statt dessen sind polymorphe Zuweisungen im Allgemeinen nur zwischen Objektsorten und Pid-Sorten möglich; bei Wertesorten ist Typgleichheit erforderlich. Genauer werden die Zuwei-sungsregeln durch die Begriffe typverträglich und unmittelbar typverträglich definiert [Z.100-00, 12.1.3]:

Seien T und V Sorten. V ist typverträglich mit T genau dann, wenn:

a) V und T dieselbe Sorte sind,

b) V unmittelbar typverträglich mit T ist, oder

c) T eine Objekt- oder Pid-Sorte ist und es eine Sorte U gibt, so dass V typverträglich mit U und U typverträglich mit T ist.

V ist unmittelbar typverträglich mit T, wenn

a) V durch die Regel <basic sort> beschrieben wird und T eine Basissorte von V ist, b) V durch die Regel <anchored sort> beschrieben wird und T die dort enthaltene Sorte ist, c) V durch die Regel <reference sort> beschrieben wird und T die dort enthaltene Sorte ist, d) T durch die Regel <reference sort> beschrieben wird und V die dort enthaltene Sorte ist, e) V durch die Regel <expanded sort> beschrieben wird und T die dort enthaltene Sorte ist, f) T durch die Regel <expanded sort> beschrieben wird und V die dort enthaltene Sorte ist, g) V eine Pid-Sorte und T eine Basissorte von V ist.

Der Begriff der Typverträglichkeit, der eine reflexive Halbordnung definiert, wird seinerseits zur Definition der folgenden Konstrukte verwendet:

• Typverträglichkeit von Operationen (6.4) und

• Zuweisungen (6.11).

Durch die Definition von Objekttypen wird es möglich, Variablen mit polymorphen Werten zu definieren. Eine solche polymorphe Variable hat einen statischen Typ und einen dynamischen Typ.

Beispiel 13. Gegeben seien folgende Definitionen:

object type Base{

struct x Integer;

}

object type Derived inherits Base{

struct y Integer;

}

dcl var Base := <<type Derived>>(. 3, 4 .);

Der statische Typ der Variablen var ist Base; der dynamische Typ ist Derived.

Die Spezialisierung von Datentypen wird durch die Regel <data type specialization> festgelegt:

<data type specialization> :: <data type<type expression> <renaming>

Innerhalb der Spezialisierung wird durch den Knoten <type expression> der Basistyp angege-ben. Dieser kann lediglich der Typname sein oder aber ein parametrisierter Basistyp, an den ak-tuelle Kontextparameter übergeben werden. Im folgenden Beispiel wird der bereits definierte parametrisierte Typ DT spezialisiert und dabei festgelegt, dass der formale Kontextparameter durch den Typ Integer aktualisiert wird.

object type DT2 inherits DT<Integer>;

endobject type;

Bei der Spezialisierung von Typen können Operationsnamen geändert werden. Dies erfolgt durch die Regel <renaming>, die ihrerseits aus einer Folge von <rename pair>-Konstrukten be-steht:

<renaming> :: <rename pair>*

<rename pair> =

<rename pair gen operation name> | <rename pair gen literal name>

Umbenennungen können sowohl Operationsnamen als auch Literalnamen (bei Aufzählungsty-pen ändern):

<rename pair gen operation name> :: <operation name> <base type<operation name>

<rename pair gen literal name> :: <literal name> <base type<literal name>

Beispielsweise könnte bei Spezialisierung des Typs DT die Operation getP umbenannt werden:

object type DT3 inherits DT<Integer>(getInt = getP);

endobject type;

Die Syntaxregel für Schnittstellenspezialisierung unterscheidet sich von der Datentypspeziali-sierung dadurch, dass bei Schnittstellen Mehrfachvererbung erlaubt ist:

<interface specialization> :: <interface<type expression>+

In der konkreten Syntax werden die Basisschnittstellen durch Kommata getrennt:

interface Derived inherits Base1, Base2;

endinterface;