Point contains
{
x, y is int;
construct( x, y );
}
x und y sind bekannt, sie sind vom Typ her int, also ist das ein Point(int, int)-Konstruktor. Die Übergaben werden direkt ins neue Objekt kopiert. Im Idealfall läuft die Konstruktion so inline ab.
Defaultargumente werden wie in C mit der Zuweisung erledigt.
Point contains
{
x, y is int;
construct( x:0, y:0 );
construct( x = 0 as int, y = 0 as int ) := // hier sind x und y neue Konstanten, hier sollte eine Warning erfolgen
{
.x : x;
.y : y;
}
construct( x is 0 as int, y is 0 as int ) := // hier sind x und y neue Variablen
{
x +: 1;
y +: 1;
.x : x;
.y : y;
}
}
Es ist zu überlegen, ob Objekte grundsätzlich Konstant zurückgegeben werden.
So würde
Point contains
{
x, y is int;
construct( x, y );
}
einen unveränderlichen Punkt zurückliefern. Damit wäre is eine reine Ableitung und verliert seine Bedeutung als mutable object. Wenn man auf 'class' geht könnte man mutable bzw. const einführen:
Point is const/var class
{
x, y is int;
construct( x, y );
}
um sich für die komplette Klasse festzulegen. Legt man sich nicht fest, könnte man nach OOP von einer mutable class ausgehen und const Konstruktoren definieren:
Point is class
{
x, y is int;
construct( x, y ) const;
}
Da Genesys allerdings maximal restriktiv sein soll, könnnte man auch von einer konstanten Klasse per Default ausgehen:
Point contains
{
x, y is int;
construct( x, y ) var;
}
Ein Konstruktor kann mit der as Anweisung Parameter gleich auf dem Zielspeicher initialisieren:
Rect contains
{
Source is Point; // erstellt expliziten construct( Point )
Target is Point; // erstellt expliziten construct( Point )
construct( Point as Source, Point as Target );
construct( Source, Target );
};
Der Construktor schreibt die übergebenen Punkte direkt nach Source bzw. Target. Erlaubt sind ( Point, Point ), aber auch ( Rect::Source, Rect::Target ). Hier findet im ersten Konstruktor ein expliziter Aufruf von Rect::Source::construct( Point ), bzw. Rect::Target::construct( Point ) statt. Im 2. Konstruktor wird ebenfalls nur durchgereicht, als Eingangstyp wird allerdings Rect::Source, bzw. Rect::Target verlangt.
Müssen Berechnungen durchgeführt werden, so können temporäre Objekte mit as - Parametern verhindert werden. Sie werden direkt im neuen Objekt erstellt:
Statt:
Point contains
{
XOffset is int;
YOffset is int;
construct( XOffset, YOffset )
};
offset as int : 4711;
x as int : offset + 10;
y as int : offset + 20;
p as Point ptr : new( x, y );
oder
Point contains
{
XOffset is int;
YOffset is int;
construct( XOffset, YOffset ) :=
print "Punkt ", XOffset$, "/", YOffset$, "konstruiert";
};
offset as int : 4711;
p as Point ptr : new( XOffset, YOffset )
{
XOffset : offset + 10;
YOffset : offset + 20;
}
Im zweiten Fall wird das Objekt erzeugt und es gibt einen gültigen Konstruktor ( XOffset, YOffset ). Der Konstruktor besteht aus zwei Teilen: Dem Initialisierungsbereich: der Zuweisung von XOffset und YOffset, die vor der print-Anweisung initialisiert werden; und eben dem Anweisungsblock mit dem Print.
new( XOffset, YOffset ) stellt klar, welcher Konstruktor verwendet wird. Alle im Konstruktor genannten Variablen müssen initialisiert werden. Anschließend wird der Anweisungsblock des Konstruktors gerufen. Die Initialisierung wurde bereits vom Benutzer übernommen.