Konstruktor und Destruktor sind, wie oben schon auffiel, zweigeteilt. Der eine Teil (die Funktion @fussballspieler beim Konstruktor bzw. analog dazu die Prozedur @fussballspieler_free beim Destruktor) dient lediglich dem Anfordern und Freigeben des Objektspeichers. Dies wird dort mittels Aufruf der Bibliotheksfunktionen @ob_create bzw. @ob_free erledigt. Nach dem Anlegen und vor dem Freigeben von Objektspeichern müssen aber meist Initialisierungs- oder Aufräumaufgaben erledigt werden. Dies geschieht dann in den Prozeduren @fussballspieler_init bzw. @fussballspieler_exit, welche aus den beiden anderen Routinen heraus aufgerufen werden:
FUNCTION fussballspieler(name$,position&,staerke&) !call ' ' Diese Funktion legt ein Objekt des Typs fussballspieler an ' und gibt die Objektkennung zurück. ' ' name$ => Name des Fußballspielers (bspw. "Lothar Matthäus") ' position& => Position, auf der der Spieler besonders stark ist. ' fussballspieler_position_tor_& ' fussballspieler_position_abwehr_& ' fussballspieler_position_mitte_& ' fussballspieler_position_sturm_& ' staerke& => Staerke des Spielers im Mittel. ' (0 = sehr schlecht, 100 = sehr gut) ' LOCAL ob# ' ' *** Objektspeicher anfordern *** ' LET ob#=@ob_create(fussballspieler_%) ' ' *** Objektspeicher initialisieren *** ' @fussballspieler_init(ob#,name$,position&,staerke&) ' RETURN ob# ENDFUNC PROCEDURE fussballspieler_free(ob#) !call ' ' Diese Prozedur entfernt ein Objekt des Typs fussballspieler aus ' dem Speicher. ' ' ' *** Objektintern "aufräumen" *** ' @fussballspieler_exit(ob#) ' ' *** Objektspeicher freigeben *** ' @ob_free(ob#,fussballspieler_%) ' RETURN
Die beiden eben aufgeführten Routinen sehen bei allen Objekttypen gleich aus. Man muß lediglich stets die Typnamen und ggf. die Parameter anpassen.
Beim Initialisieren der Objektspeicher müssen zunächst alle konkreten Attributspeicher ihrerseits korrekt initialisiert werden. Dies geschieht durch Aufruf der zum jeweiligen Typ passenden init-Prozedur. An diese init-Prozedur muß nun dementsprechend auch die Objektkennung des konkreten Attributes übergeben werden. Diese Kennung wird über eine Bibliotheksfunktion, nämlich die Funktion @ob_attrib, unter Angabe der Typ- und der Attributkennung, ermittelt:
PROCEDURE fussballspieler_init(ob#,name$,position&,staerke&) !call ' ' *** konkrete Attribute initialisieren *** ' @string_init(@ob_attrib(ob#,fussballspieler_%, fussballspieler_name_%)) @word_init(@ob_attrib(ob#,fussballspieler_%, fussballspieler_tor_%)) @word_init(@ob_attrib(ob#,fussballspieler_%, fussballspieler_abwehr_%)) @word_init(@ob_attrib(ob#,fussballspieler_%, fussballspieler_mitte_%)) @word_init(@ob_attrib(ob#,fussballspieler_%, fussballspieler_sturm_%))
Jetzt können die Attributspeicher benutzt und insbesondere mit vernünftigen Werten vorbelegt werden. Im vorliegenden Fall wird der Name des Fußballspielers gesetzt, und es werden die Spielerstärken je nach übergebener Position und Durchschnittsstärke unter Einfluß von etwas Zufall voreingestellt:
' ' *** Spieler einrichten *** ' ' +++ Name setzen +++ ' @fussballspieler_name_set(ob#,name$) ' ' +++ Stärke in Tor, Abwehr, Mitte und Sturm festlegen +++ ' (der Zufall spielt mit) ' SELECT position& CASE fussballspieler_position_tor_& ! Torwart => im Tor gut @fussballspieler_tor_set(ob#,RANDOM(20)+staerke&-10) @fussballspieler_abwehr_set(ob#,RANDOM(10)) @fussballspieler_mitte_set(ob#,RANDOM(10)) @fussballspieler_sturm_set(ob#,RANDOM(10)) CASE fussballspieler_position_abwehr_& ! Abwehr => hinten gut @fussballspieler_tor_set(ob#,RANDOM(10)) @fussballspieler_abwehr_set(ob#,RANDOM(20)+staerke&-10) @fussballspieler_mitte_set(ob#,RANDOM(staerke& DIV 3)) @fussballspieler_sturm_set(ob#,RANDOM(staerke& DIV 3)) CASE fussballspieler_position_mitte_& ! Mitte => mitte gut @fussballspieler_tor_set(ob#,RANDOM(10)) @fussballspieler_abwehr_set(ob#,RANDOM(staerke& DIV 3)) @fussballspieler_mitte_set(ob#,RANDOM(20)+staerke&-10) @fussballspieler_sturm_set(ob#,RANDOM(staerke& DIV 3)) CASE fussballspieler_position_sturm_& ! Stürmer => vorne gut @fussballspieler_tor_set(ob#,RANDOM(10)) @fussballspieler_abwehr_set(ob#,RANDOM(staerke& DIV 3)) @fussballspieler_mitte_set(ob#,RANDOM(staerke& DIV 3)) @fussballspieler_sturm_set(ob#,RANDOM(20)+staerke&-10) ENDSELECT ' RETURN
In der init-Prozedur können auch -- wie oben erwähnt -- Dateien geöffnet werden oder Internetverbindungen aufgebaut werden, falls sich die tatsächlichen Informationspeicher (oder Teile davon) an entfernten Orten befinden. Diese Dateien und Verbindungen kann man in der exit-Prozedur wieder schließen bzw. abbauen.
Anschließend muß man (umgekehrt wie beim Initvorgang) jeden einzelnen konkreten Attributspeicher ebenfalls sauber "herunterfahren", denn es könnte ja sein, daß ein solcher noch Resourcen belegt und diese seinerseits erst freigeben muß.
PROCEDURE fussballspieler_exit(ob#) !call ' ' *** konkrete Attribute freigeben *** ' @string_exit(@ob_attrib(ob#,fussballspieler_%, fussballspieler_name_%)) @word_exit(@ob_attrib(ob#,fussballspieler_%, fussballspieler_tor_%)) @word_exit(@ob_attrib(ob#,fussballspieler_%, fussballspieler_abwehr_%)) @word_exit(@ob_attrib(ob#,fussballspieler_%, fussballspieler_mitte_%)) @word_exit(@ob_attrib(ob#,fussballspieler_%, fussballspieler_sturm_%)) ' RETURN
Das Ausfüllen der Abfragefunktionen und der Operationen gestaltet sich recht monoton. Zu jedem Objekttyp stehen üblicherweise eine xxx_set-Prozedur sowie eine xxx_get-Funktion zur Verfügung, über die die Werte in die Objektspeicher eingeschrieben bzw. von dort wieder herausgelesen werden können:
FUNCTION fussballspieler_name$(ob#) !call ' ' Ermittelt den Spielernamen. ' RETURN @string_get$(@ob_attrib(ob#,fussballspieler_%, fussballspieler_name_%)) ENDFUNC FUNCTION fussballspieler_tor(ob#) !call $F% ' ' Ermittelt die Tor-Stärke des Spielers. ' RETURN @word_get(@ob_attrib(ob#,fussballspieler_%, fussballspieler_tor_%)) ENDFUNC FUNCTION fussballspieler_abwehr(ob#) !call $F% ' ' Ermittelt die Abwehr-Stärke des Spielers. ' RETURN @word_get(@ob_attrib(ob#,fussballspieler_%, fussballspieler_abwehr_%)) ENDFUNC FUNCTION fussballspieler_mitte(ob#) !call $F% ' ' Ermittelt die Stärke im Mittelfeld des Spielers. ' RETURN @word_get(@ob_attrib(ob#,fussballspieler_%, fussballspieler_mitte_%)) ENDFUNC FUNCTION fussballspieler_sturm(ob#) !call $F% ' ' Ermittelt die Sturm-Stärke des Spielers. ' RETURN @word_get(@ob_attrib(ob#,fussballspieler_%, fussballspieler_sturm_%)) ENDFUNC PROCEDURE fussballspieler_name_set(ob#,name$) @string_set(@ob_attrib(ob#,fussballspieler_%, fussballspieler_name_%),name$) RETURN PROCEDURE fussballspieler_tor_set(ob#,staerke&) !call ' ' Setzt die Tor-Stärke des Spielers. Die Werte werden auf den ' Breich 0..100 gestutzt. ' LET staerke&=MAX(0,MIN(100,staerke&)) @word_set(@ob_attrib(ob#,fussballspieler_%, fussballspieler_tor_%),staerke&) RETURN PROCEDURE fussballspieler_abwehr_set(ob#,staerke&) !call ' ' Setzt die Abwehr-Stärke des Spielers. Die Werte werden auf den ' Breich 0..100 gestutzt. ' LET staerke&=MAX(0,MIN(100,staerke&)) @word_set(@ob_attrib(ob#,fussballspieler_%, fussballspieler_abwehr_%),staerke&) RETURN PROCEDURE fussballspieler_mitte_set(ob#,staerke&) !call ' ' Setzt die Stärke im Mittelfeld des Spielers. Die Werte werden ' auf den Breich 0..100 gestutzt. ' LET staerke&=MAX(0,MIN(100,staerke&)) @word_set(@ob_attrib(ob#,fussballspieler_%, fussballspieler_mitte_%),staerke&) RETURN PROCEDURE fussballspieler_sturm_set(ob#,staerke&) !call ' ' Setzt die Sturm-Stärke des Spielers. Die Werte werden auf den ' Breich 0..100 gestutzt. ' LET staerke&=MAX(0,MIN(100,staerke&)) @word_set(@ob_attrib(ob#,fussballspieler_%, fussballspieler_sturm_%),staerke&) RETURN
Daß dies hier so monoton aussieht, ist eine Folge der oben gemachten 1:1-Kodierung. Bei Optimierungen oder bei der Verwendung externer Speicher gestaltet sich die Ermittlung und das Ändern der abstrakten Attribute dann entsprechend der gewählten Kodierung aufwendiger.