MAL-Homepage
Inhaltsverzeichnis
MAL Dokumentation: Objektorientierte Programmierung
1. EINFÜHRUNG
Objekte (Instanzen) werden am Mal-Stack durch den
Datentyp 'instancetyp' repräsentiert. Dieser Datentyp ist
weitgehend funktionsgleich mit einem Verbund. Er wird
auch durch Aufruf des Wortes
>instance
direkt aus einem Verbund erzeugt. Die Komponenten des
Verbundes sollten sinnvoller Weise mit Namen versehen sein.
Für die Zuordnung des Objekts zu seiner Klasse ist
der Klassenname als String mit dem Namen 'class' im Verbund enthalten.
Beispiel eines Objekts einer Klasse für komplexe Zahlen:
[ "complex_class" "class" >name 5 "real" >name 3 "imag" >name ] >instanceDieses Objekt stellt eine Instanz der Klasse 'complex_class' mit dem Wert der komplexen Zahl 5+3j dar.
MAL-Homepage Inhaltsverzeichnis
2. KLASSEN
Jede Klasse ist eine Doppelpunktdefinition. Das Grundgerüst einer
Klasse ohne Member-Functions hat folgenden Aufbau:
: klassenname >> function : classname "klassenname" ; : interface [ . . ] ; function >code make ;Der unter : classname ... angegebene Klassenname muß mit dem Namen der der Doppelpunktdefinition ident sein.
MAL-Homepage Inhaltsverzeichnis
2.1. Member-Functions
Member-Functions werden in Form von lokalen Doppelpunktdefinitionen
in der Klasse definiert. Damit sie auf elegante Weise aufgerufen werden
können, muß zusätzlich noch ein String im Verbund des
Wortes interface eingebracht werden, der die Aufrufsyntax
der Member-Function deklariert.
Ein Deklarations-String hat folgende Parameter:
: interface [ "+:addition this x -> summe" ] ;Der externe Name der Funktion ist '+', der interne 'addition'. Sie erwartet zwei Input-Paramerer, nämlich 'this' und 'x', die beide Instanzen der eigenen Klasse sind. Als Ergebnis wird ebenfalls eine Instanz der eigenen Klasse am Stack gelegt (die Summe der Komplexen Zahlen 'this' und 'x').
: addition real x \ real + -> real imag x \ imag + -> imag this> ;
MAL-Homepage Inhaltsverzeichnis
2.2. Konstruktoren
Die Namen von Konstruktor-Funktionen können in MAL frei
vergeben werden. Konstruktoren unterscheiden sich von sonstigen
Member-Functions nur dadurch, daß sie als Input-Parameter
keine Instanzen der eigenen Klasse benötigen, jedoch welche
als Output-Parameter erzeugen.
Als Hilfsmitte für das Erzeugen von Instanzen der eigenen
Klasse können die Worte {
und } verwendet werden.
Diese sind wie folgt definiert:
: { [ classname "class" >name ; : } ] >instance ;Wenn man also zum Beispiel einen Konstruktor für komplexe Zahlen folgendermaßen implementiert:
: >complex { cool real cool imag } ;so entspricht das folgendem Code:
: >complex [ classname "class" >name cool real cool imag ] >instance ;Das bewirkt, daß zuerst der Name der Klasse in den Verbund aufgenommen wird, dann der Realteil (das Wort cool bewirkt, daß dem Stackeintrag automatisch der Name des Wortes, also 'real', gegeben wird) und der Imaginärteil, und im Anschluß der Verbund auf eine Instanz umgewandelt wird.
MAL-Homepage Inhaltsverzeichnis
3. ANWENDUNG EINER KLASSE
Mit dem Code
interface_of complex_class >vocwird das Interface der Klasse complex_class ins Vokabular geladen. Die Worte >complex und + können also direkt aufgerufen werden:
1 2 >complex 3 4 >complex + .gibt als Ergebnis:
instance-[ class=complex_class real=4 imag=6 ]Man beachte, daß der MAL-Interpreter das neue Wort + v on dem bereits im Kern definierten unterscheiden kann. Die normale Addition ist nach wie vor möglich:
1 2 + . 3
MAL-Homepage Inhaltsverzeichnis
4. VERERBUNG
Vererbung, also die Konstruktion abgeleiteter Klassen, stellt
ein wesentliches Stilmittel der Objektorientierten Programmierung dar.
Zwei Charakteristika zeichnen eine abgeleitete Klasse aus:
MAL-Homepage Inhaltsverzeichnis
4.1. Vererbund der Variablen
Die Instanzen einer abgeleiteten Klasse unterscheiden sich
von denen ihrer Oberklasse primär durch den eingetragenen
Klassennamen ( also den String mit dem Namen 'class').
Außerdem können sie zusätzliche Variablen beinhalten.
Die Übernahme der Daten aus der Oberklasse erfolgt im
Konstruktor (den Konstruktoren) der abgeleiteten Klasse
durch das Wort inherit.
Das Wort inherit hat folgende Syntax:
d_instanz instanz -> var1 var2 ...
: konstruktor { . . . } konstruktor_oberklasse inherit ;
MAL-Homepage Inhaltsverzeichnis
4.2. Vererbung der Funktionen
Wenn nach der Interface-Deklaration einer Klasse der Code
derived_from xxx ( xxx ist die Oberklasse)aufgerufen wird, so können alle Member-Functions der Oberklasse für die Instanzen der abgeleiteten Klasse verwendet werden. Das Interface der abgeleiteten Klasse wird also um die Funktionen der Oberklasse erweitert.
[ "create_segment_assignment: -> this " "get_patterns: this -> patterns:[] " ] derived_from neural_class ;In MAL hat eine abgeleitete Klasse immer Zugriff auf alle Member-Functions und Variablen ihrer Oberklasse. Es gibt also keine 'private' Direktiven oder ähnliches.
MAL-Homepage Inhaltsverzeichnis
4.3. Beispiel für Vererbung
Als Beispiel für die Vererbung wird hier eine Klasse personen_class
(als Oberklasse) mit den Variablen Vorname und Familienname angeführt.
Sie ist wie folgt definiert:
: personen_class >> function : classname "Person" ; : interface [ ">person vorname:string familienname:string -> this" ] ; : >person_ { cool vorname cool familienname } ; function >code make ;Von ihr abgeleitet ist die Klasse angestellter_class, mit der zusätzlichen Variable Einstellungsdatum und den zusätzlichen Funktionen >angestellter (Konstruktor) und angestellt_am:
: Angestellter >> function : classname "Angestellter" ; : interface [ ">angestellter: vorname:string familienname:string -> this" "angestellt_am: this datum:string -> this" ] derived_from Person ; : >angestellter_ { vorname familienname >person inherit "" "Einstellungsdatum" >name } ; : angestellt_am_ datum -> Einstellungsdatum this> ; function >code make ;Der Code derived_from Person im Interface wäre in diesem Fall gar nicht erforderlich, da von der Oberklasse keine Funtionen verwendet werden (außer dem Konstruktor >person, der aber direkt von der Klasse Person aufgerufen wird).
MAL-Homepage Inhaltsverzeichnis
5. MENÜGESTEUERTE ENTWICKLUNGSUMGEBUNG
Die menügesteuerte Entwicklungsumgebung für Klassen ist nicht
nur für den Aufbau der Klassenstruktur sehr hilfreich, sie
unterstützt auch die Dokumentation der Klasse, indem sie
die Helpseite automatisch aus den bei den Funktionen und
Variablen angegebenen Informationen generiert.
Sie unterstütz aber nur die Entwicklung von Klassen, die
in einem Vokabulars-Folder
gespeichert sind.
Hinweis:
Eine Klasse ist eine normale Doppelpunktdefinition.
Für die menügesteuerte Entwicklungsumgebung
wird aber der Environment-Datensatz dieser Doppelpunktdefinition
für das Abspeichern der eingebenen Daten verwendet.
Dazu wird der Code im Environment dynamisch verändert (beim Sichern
der Änderungen). Die Datensätze code und help
der Klasse werden ebenfalls beim Sichern automatisch generiert.
Veränderungen der Klasse dürfen daher nur mehr über die Entwicklungsumgebung
durchgeführt werden, da sonst Inkonsistenzen entstehen können.
MAL-Homepage Inhaltsverzeichnis
5.1. Einrichten einer Klasse
Die menügesteuerte Entwicklungsumgebung erspart
den manuellen Aufbau der Klassenstruktur und der Helptext-Seite.
Eine neue Klasse mit Entwicklungsumgebung wird eingerichtet, indem
von einem Vokabulars-Folder
aus der Menüpunkt insert / Class
aufgerufen wird.
MAL-Homepage Inhaltsverzeichnis
5.2. Bedienung
Mit dem Menüpunkt go wird die Entwicklungsumgebung gestartet.
Daraufhin erscheint ein Menü mit folgenden Menüpunkten:
MAL-Homepage Inhaltsverzeichnis