Strukturen und Objekte
Wir können auch anders
Bisher vorgestellte Programme waren in funktionaler Weise implementiert. Schemes Stärken liegen zwar hauptsächlich in diesem Bereich, jedoch gibt es auch die Möglichkeit, objektorientiert vorzugehen.
Bisher vorgestellte Programme waren in funktionaler Weise implementiert. Schemes Stärken liegen zwar hauptsächlich in diesem Bereich, jedoch gibt es auch die Möglichkeit, objektorientiert vorzugehen.
Der zweite Teil dieser Reihe zeigte, wie in Scheme Strukturen definiert werden. Da die berühmte Gleichung des Methodikers Niklaus Wirth "Algorithmen + Datenstrukturen = Programme" immer noch gilt, wäre Scheme weniger nützlich, wenn es nicht auch Datenstrukturen gäbe. Sie können Strukturen in DrScheme so anlegen wie in Listing 1. Bei der Benutzung von define-struct wird eine Reihe von Funktionen automatisch generiert. Für jede Struktur erhalten Sie:
Die Verschachtelung von Strukturen erfolgt in der zweiten Form: (define-struct (neue-Struktur struct:alte-Struktur) (neue-Felder)) . Dabei sollten Sie beachten, dass nur den neuen Feldelementen der neue Strukturname vorangestellt wird. Sie müssen daher genau wissen, welche Elemente von der alten Struktur übernommen und welche neu eingeführt wurden. Da ich dies für nicht besonders einsichtig halte, schlage ich vor, noch eine Erweiterung von DrScheme zu nutzen: dessen Objektsystem.
Die objektorientierte Programmierung erfreut sich immer noch steigender Beliebtheit, obwohl gewisse Vorstellungen über die unbedingte Nützlichkeit schon wieder in Frage gestellt werden. Lisps waren und sind Sprachen, die weitere Paradigmen umarmen, aber nicht erdrücken.
Es gibt eine Reihe von Objektsystemen für Scheme; da in den Beispielen DrScheme genutzt wurde, bietet es sich an, dessen Ansatz genauer zu untersuchen. Die Charakteristika des Systems entsprechen denen von Java:
Die Interface-Vererbung wird in diesem Artikel nicht vorgestellt; wenn Sie sich darüber kundig machen wollen, schlagen Sie bitte in [4] nach. Eine Klassendefinition in Scheme sieht aus wie in Listing 2 dargestellt.
Eine Klasse bekommt ganz herkömmlich mit define einen Namen zugewiesen. Die Klassendefinition wird mit class eingeleitet, danach wird die Superklasse aufgeführt (hier object%). In DrScheme handelt es sich dabei um den Vorfahren aller Klassen, es gibt also keinen spezialisierteren Vorgänger. DrScheme folgt der Namenskonvention, Klassen mit einem % abzuschließen. Es empfiehlt sich, einer solchen Konvention zu folgen, da sie den Erwartungen anderer Benutzer entspricht.
In der nachfolgenden Liste werden die Initialisierungsvariablen aufgezählt. Das sind Variablen, die bei der Erzeugung eines Objekts dieser Klasse übergeben werden müssen. Im Beispiel handelt es sich um first-name und last-name.
Im mit private beginnenden Abschnitt erfolgt die Deklaration privater Attribute dieser Klasse ( p1%). Es ist dabei wie immer unerheblich, ob es sich um Funktionen oder Variablen handelt. Die Variablen im Beispiel sind fname und lname, denen die Initialisierungsvariablen first-name und last-name zugeordnet werden. Für den Zugriff von anderen Klassen werden Zu-griffsfunktionen angeboten (Kommentar ; 1). Bitte beachten Sie, dass keine Möglichkeit vorgesehen ist, den Vornamen einer Person zu ändern, wohl aber deren Nachnamen.
Eventuell erklärungsbedürftig ist die Funktion, mit der die Zugehörigkeit eines Objekts zu dieser Klasse getestet wird. Der Name für das Objekt selbst ist this, somit sind C++-Programmierer im Vorteil. Der noch zu klärende Teil ist die Zeile (sequence (super-init)). In jeder Klasse, die Sie definieren, muss an einer Stelle die Initialisierungsmethode des Vorgängers aufgerufen werden, um dessen Instanzvariablen anzulegen. Damit ist die erste Klasse in Scheme implementiert. Betrachten wir einmal, wie ein Objekt angelegt und manipuliert werden kann (Listing 3).
Mit send wird eine Nachricht an ein Objekt versandt, mit ivar auf Instanzvariablen zugegriffen. Für das Anlegen eines Objekts steht die Funktion make-object zur Verfügung. Diese Funktion wird automatisch (wahrscheinlich durch ein Makro) definiert und erwartet als ersten Parameter einen Klassennamen. Nachfolgende Parameter sind die geforderten Initialisierungsparameter, im Beispiel handelt es sich um zwei Parameter. Es bleibt also festzuhalten:
Betrachten wir nun, wie Vererbung in DrScheme genutzt werden kann.
Alle Rezensionen aus dem Linux-Magazin
Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...