Sonntag, 17. Januar 2010

Metaklassen in Objective-C und Common Lisp

In einem meiner Lieblingsblogs, Matt Gallaghers "Cocoa with Love", ist heute ein Artikel über Metaklassen in Objective-C erschienen. Für Lisp-Fans sind Metaklassen natürlich kein neues Thema; Common Lisp ist eine der wenigen Programmiersprachen, deren Objektsystem CLOS selbst-reflektiv in sich selbst entwickelt ist. Die Programmierschnittstelle dafür nennt man das Metaobjektprotokoll (MOP).

Metaklassen in Objective-C

Matt Gallagher zeigt in seinem Artikel, wie die Objective-C-Runtime Objekte realisiert. Als C-Struktur betrachtet, ist das erste Element jedes Objekts in Objective-C ein Zeiger auf seine Klasse. Klassen wiederum sind in Objective-C ebenfalls Objekte; folglich ist deren erstes Element ebenfalls ein Zeiger auf ihre Klasse: Die Metaklasse. Dieses Spiel könnte vermutlich in infinitem Regress immer so weiter gehen – wäre da nicht eine kleine Besonderheit. NSObject, die Wurzel des Objective-C-Klassenbaums ist selbst ein NSObject. Das erste Element des Objekts NSObject zeigt auf die Klasse NSObject.

In Objective-C sind Methoden Bestandteil von Klassen; wie wohl in den meisten heutigen Programmiersprachen. Sendet man eine Nachricht an ein Objekt, dann wird zuerst die Klasse ermittelt und in deren Liste der Methoden die passende Methode gesucht. Ist dort keine passende Methode, so wird dasselbe mit der Superklasse probiert. Da Klassen ja selbst auch Objekte sind können sie auch Methoden haben (also Rezepte wie sie auf bestimmte Nachrichten reagieren). Die Methoden einer Klasse nennt man Klassenmethoden; typische Beispiele dafür sind alloc oder init. Die Klasse eines Objekts enhält also die Liste seiner Methoden; die Metaklasse eines Objekts (Klasse der Klasse) enthält die Klassenmethoden. Da jede definierte Klasse eigene Methoden haben kann, benötigt in Objective-C jede Klasse eine eigene Metaklasse.

Metaklassen in Common Lisp (CLOS)

In Common Lisp (CL) hat ebenfalls jede Klasse eine zugehörige Metaklasse. Allerdings hat nicht jede Klasse eine eigene; im Gegenteil – fast alle Klassen besitzen die Metaklasse STANDARD-CLASS. Für CL sind Klassen keine Methodenbehälter – Methoden gehören zu Generischen Funktionen (GF); das sind Funktionen deren Parameter auf bestimmte Klassen eingeschränkt werden können. Die Auswahl einer Methode (Method Dispatch) erfolgt in CL also nach allen Parametern der Funktion. Common Lisp besitzt also eine eher funktional orientierte Art der Objektorientierten Programmierung. Man definiert Protokolle aus Generischen Funktionen; je nach beteiligten Objekten laufen diese Protokolle anders ab. Beim klassischen Message-passing beschreiben die Methoden eines Objekts dessen Verhalten bei bestimmten Nachrichten. Die (restlichen) Parameter der Methode sieht das Objekt und kann sein Handeln danach orientieren. Im CL Objektsystem dagegen, beschreiben Methoden die Interaktion von bestimmten Objekten aus der Sicht eines objektübergreifenden Protokolls. Natürlich kann man sich bei CLOS auch darauf beschränken, lediglich den ersten Parameter einer Generischen Funktion zu spezialisieren; das System degeneriert dann zu einem herkömmlichen Single-Dispatch-System.

Neue Metaklassen definiert man in Common Lisp nur, wenn man die Protokolle des Objektsystems anpassen möchte: Wie werden Werte aus Objekten gelesen und gespeichert? Wie werden neue Objekte erzeugt? Viele andere Dinge sind denkbar

Keine Kommentare:

Kommentar veröffentlichen