Objekte sind Instanzen von Klassen. Jedes Objekt hat eine eindeutige Identität und eigene Attribute. Alle transienten Objekte leben gleichberechtigt im Kontext eines internen Modus (Speicherbereich eines ABAP Programms). Persistente Objekte in der Datenbank stehen zum derzeitigen Release noch nicht zur Verfügung. Zu einer Klasse kann es beliebig viele Objekte bzw. Instanzen geben.
Der Zugriff eines ABAP-Programms auf Objekte erfolgt ausschließlich über Objektreferenzen. Objektreferenzen sind Zeiger auf Objekte und kommen in ABAP ausschließlich als Inhalt von Objektreferenzvariablen vor.
Objektreferenzvariablen sind neben Datenreferenzvariablen für Datenreferenzen einer der beiden möglichen Typen von Variablen, die in ABAP Referenzen enthalten können. Objektreferenzvariablen enthalten Referenzen auf Objekte. Eine Objektreferenzvariable ist entweder initial oder enthält eine Referenz auf ein bestehendes Objekt. Die Identität eines Objekts hängt an der Objektreferenz. Eine Referenzvariable, die auf ein Objekt zeigt, kennt die Identität des Objekts. Die instanzgebundenen Komponenten eines Objekts können nur über solche Referenzvariable angesprochen werden, die auf das Objekt zeigen.
Ein Verwender hat keinen direkten Zugriff auf die Objektidentität. Referenzvariablen arbeiten mit Referenzsemantik. Bei der Referenzsemantik wird bei Zuweisung einer Referenzvariablen auf eine andere nur die Adresse des Objekts, also die Objektreferenz, übergeben und nicht die Attribute des Objekts. Objektattribute können natürlich selbst Referenzvariablen sein.
Objektreferenzvariablen werden wie andere Variable auch mit der Anweisung CLEAR initialisiert. Der Initialwert einer Referenzvariablen ist eine Referenz, die auf kein Objekt zeigt.
ABAP enthält einen eingebauten Datentyp für Referenzen, der mit den eingebauten Datentypen für Strukturen oder für interne Tabellen vergleichbar ist. Der vollständige Datentyp wird dabei erst bei der Deklaration im ABAP-Programm definiert. Der Datentyp einer Objektreferenzvariable bestimmt, wie das Programm ihren Wert, also die Objektreferenz, behandelt. Es gibt zwei prinzipielle Arten von Objektreferenzen: Klassenreferenzen und Interfacereferenzen (siehe Interfaces).
Klassenreferenzen werden vollständig mit dem Zusatz
... TYPE REF TO class
der TYPES- oder DATA-Anweisung definiert, wobei class eine Klasse bezeichnet. Eine Referenzvariable vom Typ Klassenreferenz heißt Klassenreferenzvariable oder ebenfalls kurz Klassenreferenz.
Eine Klassenreferenz cref ermöglicht es einem Verwender, eine Instanz (Objekt) der zugehörigen Klasse anzulegen und über
cref->comp
auf alle ihm sichtbaren Komponenten comp des Objekts zuzugreifen, die auch in der Klasse class vorhanden sind.
Nachdem zuvor eine Klassenreferenzvariable cref mit Bezug auf eine Klasse class definiert wurde, kann eine Instanz (Objekt) der Klasse erzeugt werden:
CREATE OBJECT cref [TYPE class].
Diese Anweisung erzeugt eine Instanz der Klasse class und die Referenzvariable cref enthält eine Referenz auf dieses Objekt. Der Zusatz TYPE class ist in diesem Fall nicht notwendig. Er spielt eine Rolle, wenn eine Instanz einer Klasse class bei der Vererbung mit einer Klassenreferenzvariablen cref, die nicht den Typ der Klasse class hat, oder bei der Verwendung von Interfaces mit einer Interfacereferenzvariablen iref erzeugt werden soll. Hinter TYPE kann die Klasse mit der üblichen Klammersyntax auch dynamisch als Inhalt eines Felds angegeben werden.
Ein Programm kann auf die ihm sichtbaren Instanzkomponenten eines Objekts ausschließlich über Referenzen in Objektreferenzvariablen zugreifen. Dies geschieht mit dem Objektkomponentenselektor -> (ref ist eine Referenzvariable):
· Zugriff auf ein Attribut attr: ref->attr
· Aufruf einer Methode meth: CALL METHOD ref->meth
Auf statische Komponenten kann außer über Referenzvariablen auch über den Klassennamen und dem Klassenkomponentenselektor => zugegriffen werden. Auf die statischen Komponenten einer Klasse kann auch zugegriffen werden, ohne dass zuvor ein Objekt erzeugt wird:
· Zugriff auf ein statisches Attribut attr: class=>attr
· Aufruf einer statischen Methode meth: CALL METHOD class=>meth
In diesem Zusammenhang ist zu bemerken, dass sich die Eigenschaften von Instanzattributen wie statische Komponenten verhalten. Man kann sich also in einem LIKE-Zusatz über den Klassenkomponentenselektor oder über Referenzvariablen ohne vorherige Erzeugung eines Objekts auf die sichtbaren Attribute einer Klasse beziehen.
Jede Klasse enthält implizit immer die Referenzvariable me. Die Referenzvariable me enthält in Objekten immer eine Referenz auf das jeweilige Objekt selbst und wird deshalb auch Selbstreferenz genannt. Innerhalb einer Klasse kann mit der Selbstreferenz me auf die eigenen Komponenten zugegriffen werden:
· Zugriff auf ein eigenes Attribut attr: me->attr
· Aufruf einer eigenen Methode meth: CALL METHOD me->meth
Beim Arbeiten mit Attributen der eigenen Klasse in Methoden muss aber keine Referenzvariable angegeben werden. Die Selbstreferenz me wird vom System implizit gesetzt. Die Selbstreferenz ermöglicht es aber einem Objekt, anderen Objekten eine Referenz auf sich selbst zu übergeben. Weiterhin kann innerhalb eines Objekts in Methoden auf Attribute zugegriffen, werden die von lokalen Attributen der Methode verschattet werden.
In einem Programm können beliebig viele Objekte der gleichen Klasse angelegt werden. Diese Objekte sind voneinander völlig unabhängig. Sie haben jeweils eine eigene programminterne Identität und enthalten eigene Attribute. Jede CREATE OBJECT -Anweisung erzeugt ein neues Objekt, dessen Identität durch die eindeutige Objektreferenz definiert ist.
Referenzen können zwischen Referenzvariablen zugewiesen werden (Anweisung MOVE). Somit können die Referenzen in mehreren Objekteferenzvariablen auf das gleiche Objekt zeigen (Sharing). Bei Zuweisungen zwischen Referenzvariablen, müssen deren Typen entweder kompatibel oder konvertierbar sein.
Bei Zuweisungen zwischen Objektreferenzvariablen mit der MOVE-Anweisung bzw. mit dem Zuweisungsoperator (=) muss statisch, also schon bei der Syntaxprüfung erkannt werden, ob eine Zuweisung möglich ist. Das gleiche gilt bei der Übergabe von Objektreferenzvariablen als Parameter an Prozeduren. Bei der Anweisung
cref1 = cref2
müssen die beiden Klassenreferenzen cref1 und cref2 vom gleichen Typ sein, sich also auf die gleiche Klasse beziehen oder die Klasse von cref1 ist eine Oberklasse der Klasse von cref2. Insbesondere kann cref1 die vordefinierte leere Klasse OBJECT sein. Die Klasse OBJECT ist Oberklasse aller Klassen in ABAP Objects und hat keine Komponenten. Sie spielt für Referenzvariablen die gleiche Rolle, wie der Datentyp ANY für normale Variablen. Referenzvariablen vom Typ OBJECT können als Behälter für die Übergabe von Referenzen dienen. Sie können aber nicht für den Zugriff auf Objekte verwendet werden.
Weiterhin sind folgende Beziehungen mit Interfacereferenzvariablen statisch überprüfbar:
iref1 = iref2.
Beide Interfacereferenzen müssen sich auf das gleiche Interface beziehen oder das Interface von iref2 muss geschachtelt sein, wobei das Interface von iref1 als Komponente enthalten ist.
iref1 = cref1.
Die Klasse der Klassenreferenz cref1 oder eine ihrer Oberklassen muss das Interface der Interfacereferenz iref1 implementieren. Die Implementierung kann direkt oder über ein geschachteltes Interface erfolgen, welches das Interface von iref1 als Komponente enthält.
cref1 = iref1.
Hier muss die Klasse von cref1 OBJECT sein. D.h. die Referenzvariable cref1 muss den Typ REF TO OBJECT haben.
In allen Fällen, in denen eine statische Typprüfung nicht möglich ist, und immer dann, wenn Typprüfungen erst zur Laufzeit eines Programms stattfinden sollen, muss mit der Anweisung
MOVE ... ?TO ...
bzw. dem Casting-Operator (?=) gearbeitet werden. Die Casting-Zuweisung ersetzt den Zuweisungsoperator (=). Bei der Anweisung MOVE ... ?TO bzw. mit der Casting-Zuweisung findet keine statische Typprüfung statt, sondern das System prüft zur Laufzeit, ob die Objektreferenz in der Ausgangsvariablen auf ein Objekt zeigt, auf das auch die Objektreferenz in der Zielvariablen zeigen kann. Falls eine Zuweisung möglich ist, findet diese statt, ansonsten wird der abfangbare Laufzeitfehler MOVE_CAST_ERROR erzeugt
Casting ist in allen Fällen syntaktisch zwingend vorgeschrieben, in denen kein statische Typprüfung stattfinden kann, zum Beispiel:
cref1 ?= iref1.
Zuweisung einer Interfacereferenz zu einer Klassenreferenz. Damit das Casting erfolgreich ist, muss das Objekt, auf das iref1 zeigt ein Objekt der gleichen Klasse sein, wie die Klasse der Klassenvariablen cref1, oder einer ihrer Unterklassen.
Ein Objekt lebt solange es im Programm verwendet wird. Ein Programm verwendet ein Objekt solange mindestens eine Referenz auf es zeigt oder mindestens eine Methode des Objekts als Ereignisbehandler registriert ist.
Sobald auf ein Objekt keine Referenz mehr besteht und keine seiner Methoden mehr als Ereignisbehandler registriert ist, kann es von der automatischen Speicherverwaltung gelöscht werden (Garbage Collection). Dadurch wird die Identität des Objekts frei und kann von einem neuen Objekt eingenommen werden.
Siehe auch: