Eine andere Art von Mehrfach-Vererbung, sogenannte Mixins, wurde in [BC90] eingeführt. Dabei kann einer der Vater-Klassen keine eigenen Instanzen haben, vielmehr existiert sie nur, damit eine Menge von Eigenschaften von ihr geerbt werden kann. Typischer Weise wird diese abstrakte Mixin-Klasse für genau diese Zwecke geschaffen.
In Ada kann man Mixins mit Hilfe von Typerweiterung und generischen Einheiten realisieren. Dabei definiert die generische Einheit die Mixin-Klasse und der Typ, der als aktueller generischer Parameter übergeben wird fungiert als ,,Vater``.
Als Beispiel diene die Möglichkeit, beliebige Objekte mit einer Version zu versehen.
with OM; -Objekt-ManagerbieteteindeutigeObjekt-IDsan
Ein typisches Beispiel für kaskadierende Mixins ist ein Window-System. Wir beginnen mit einem einfachen Basis-Window und verschiedenen Operationen
type Basic_Window is tagged limited private;
procedure Display(W: in Basic_Window);
procedure Mouse_Click(
W: in out Basic_Window;
Where: in Mouse_Coords);
generic
type Some_Window is abstract new Basic_Window with private;
package Label_Mixin is
type Window_With_Label is abstract new Some_Window with private;
-einigeOperationenwerdenneudefiniert
procedure Display(W: in Window_With_Label);
-einigeneuekommendazu
procedure Set_Label(
W: in out Window_With_Label;
S: in String);
function Label(
W: Window_With_Label)
return String;
private
type Window_With_Label is abstract new Some_Window with
record
Label: String_Quark := Null_Quark;
-eineX-Windows-artigeeindeutigeIDfuereinenString
end record;
end Label_Mixin;
Im Body dieses generischen Pakets implementieren wir die überdefinierten und neu hinzu gekommenen Operationen. Zum Beispiel kann die neue Version von Display wie folgt aussehen
procedure Display(W: Window_With_Label) is
begin
Display(Some_Window(W));
-daszugrundeliegendeWindowwirdangezeigt,
-indemmandieOperationdesVatertypsverwendet
if W.Label
-jetztwirdderLabelausgegeben,wennervorhandenist
Display_On_Screen(XCoord(W), YCoord(W)-5, Value(W.Label));
end if;
end Display;
Wir können nun eine ganze Reihe solcher Pakete deklarieren und schließlich schreiben.
package Frame is
type My_Window is new Basic_Window with private;
private
package Add_Label is new Label_Mixin(Basic_Window);
package Add_Border is new Border_Mixin(Add_Label.Window_With_Label);
package Add_Menu_Bar is new Menu_Bar_Mixin(
Add_Border.Window_With_Border);
type My_Window is new
Add_Menu_Bar.Window_With_Menu_Bar with null record;
end Frame;
Die verschiedenen Operationen der unterschiedlichen Mixins können durch Renames-Anweisungen im Paket-Body selektiv auch vom Paket Frame angeboten werden.
Johann Blieberger