Sonntag, 7. September 2008

Das Objekt an sich

Während ich mich noch an Zeiten erinnern, als Objekte noch als unheimliche, neue Technologie galten, hat sich der objektorientierten Ansatz in den letzten Jahren weitgehend durchgesetzt. Wenn man aber verschiedene Programmiersprachen vergleicht, so erkennt man, daß das Verständnis, was ein Objekt ist, doch deutlich variiert. Egal was man verwendet, so erscheint es mir doch immer hilfreich, zu verstehen, welche Möglichkeiten es gibt und was die konkrete Implementierung bedeutet.

Im Lehrbuch findet man ungefähr folgendes: ein Objekt besitzt einen Zustand und Methoden. Es ist die Instanz einer Klasse und diese Klassen können Eigenschaften von anderen Klassen durch Vererbung übernehmen. Wenn man eine Klasse implementiert, so definiert man den Zustand gewöhnlich durch Attribute.

Attribute

Zunächst ist es hilfreich zu unterscheiden, daß es zwei Arten von Attributen gibt. Die ersten definieren die Identität des Objekts. Sie sind unveränderlich und werden deshalb bei der Erzeugung des Objekts definiert. Wenn ein Objekt z. B. eine Person repräsentiert, werde das Geburtsdatum ein solches Attribut. In einigen Programmiersprachen werden solche Attribute als konstant oder statisch gekennzeichnet.

Die zweite Art von Attributen ändert sich während der Lebenszeit des Objektes. Man kann die Unterscheidung hier noch weiter treiben, wenn man feststellt, daß sich mit Änderung des Attributs in einigen Fällen das Verhalten des gesamten Objektes ändert. Wenn sich die Temperatur eines Raumes in angemessenem Maße ändert, bleibt die Funktion des Raumes doch erhalten. Wenn sich aber der Zustand eines Autos von fahrbereit in Schrott ändert, werden dieselben Methoden anschließend zu unterschiedlichen Ergebnissen führen.

Wenn alles ein Objekt ist, dann stellen Attribute immer nur Beziehungen zu anderen Objekten dar. Dies würde prinzipiell zu einer unendlichen Rekursion führen. Daher gibt es in den meisten Programmiersprachen primitive Typen wie Zahlen und Wahrheitswerte, die nur ihren Wert repräsentieren. Will man das vermeiden, so führt man Klassen ein, deren Objekte einen bestimmten Wert repräsentieren, diesen aber nicht als Attribut besitzen. Ein derartiges Objekt besitzt nur eine Identität aber keine Attribute.

Eine weit verbreitete Ansicht ist, daß man nei direkt auf Attribute zugreifen, sondern immmer Zugriffsfunktionen nutzen soll. Einige Programmiersprachen erzwingen diese Art der Programmierung, zum Beispiel Ruby und Smalltalk. Welche Gründe gibt es dafür? Die Antwort hängt von der Art des Attributs ab. Attribute die die Identität des Objekts definieren, sollten nur einmal bei der Erzeugung des Objekts gesetzt werden können. Später sollte nur Lesezugriff möglich sein. Attribute die den Zustand eines Objekts beschreiben, sollten die direkt gesetzt werden, sondern ändern sich nur in Folge von Ereignissen. Wenn das Objekt nur ein Container für das Attribut ist, so brauchen wir in der Regel Schreib- und Lesezugriff, aber es kann ein Objekt gegeben, die über die Änderung des Wertes informiert werden wollen, wie zum Beispiel die Java Bean Spezifikation beschreibt.

Ein anderer Grund, Zugriffsfunktionen zu verwenden, ist der, daß man die innere Repräsentation der Werte ändern können will, ohne die Schnittstelle zu beeinflussen. Werte, die man nach außen sichtbar macht, müssen unter Umständen intern gar nicht vorhanden sein. Das Lehrbuchbeispiel hierzu sind kartesische und Winkelkoordinaten, von denen man nur ein Paar abspeichern muß, während sich das andere ergibt.

Methoden

Neben Attributen besitzt ein Objekt auch Methoden. Es empfiehlt sich, streng zu trennen zwischen Methoden, die eine Information über das Objekt zurückgeben und Methoden, die das Objekt ändern. Das ist eine Regel, die von keiner mir bekannten Programmiersprache erzwungen wird, aber die Verständlichkeit der Schnittstelle deutlich erhöht. Niemand wird damit rechnen, daß eine Wiederholung von Abfragen andere Werte zurückgegeben werden.

In einigen Programmiersprachen werden Methoden als Objekte behandelt. Sie können dann in Variablen abgespeichert werden oder als Rückgabewert von Methoden auftauchen. Zum Beispiel bei Python erfolgt der Zugriff auf Methoden völlig identisch wie der Zugriff auf Attribute.

In einigen Programmiersprachen, die auch den direkten Zugriff auf Attribute kennen, gibt es spezielle Methoden, die sich mit der gleichen Syntax aufrufen lassen, mit der auch auf Attribute zugegriffen wird. Dadurch wird es transparent, ob ein Attribut direkt angesprochen wird oder über Zugriffsmethoden. Populärstes Beispiel hierfür sind die Properties von C#.

Programmiersprachen, die keine strikte Typprüfung durchführen, erlauben es in der Regel, eine Methode zu definieren, die immer dann aufgerufen wird, wenn die eigentlich gefragte Methode nicht definiert ist. Das macht unter anderem die Programmierung von Proxies zu einer trivialen Übung.

Wenn eine strikte Typisierung gefordert ist, gibt es häufig die Möglichkeit, daß eine Zusage gemacht wird, daß eine bestimmte Menge von Methoden unterstützt wird. Dies geschieht durch die Interfaces, die man zum Beispiel in Java und C# findet. Man kann dann Objekte benutzen, die nur eine bestimmte Funktionalität zusagen, ohne den genauen Typ zu kennen.

Ausblick

Ich will hier kein Lehrbuch schreiben, sondern nur meine Sicht der objektorientierten Programmierung vorstellen. Einige Aspekte habe ich bislang weggelassen. Der wichtigste ist natürlich die Vererbung. Darauf will ich bei gegebener Zeit zurückkommen.


Keine Kommentare: