Diesen Artikel habe ich ursprünglich im SAP Community Network veröffentlicht.
In den vergangenen ABAP-Fallen-Blogs habe ich über verschiedene Probleme geschrieben, die beim Schreiben von Code in ABAP auftreten können. Beim heutigen Thema geht es eher um ein strukturelles oder gestalterisches Problem. Für dieses Beispiel verwenden wir die folgende Klassenhierarchie:

IMPORTING
Stellen Sie sich eine Methode vor, die eine Instanz von CL_SUPER
verwendet, um eine beliebige Operation auszuführen:
METHODS bar
IMPORTING ir_object TYPE REF TO cl_super.
...
DATA: lr_super TYPE REF TO cl_super,
lr_sub1 TYPE REF TO cl_sub1,
lr_sub2 TYPE REF TO cl_sub2.
...
lr_foo->bar( lr_super ).
lr_foo->bar( lr_sub1 ).
lr_foo->bar( lr_sub2 ).
Das ist ziemlich einfach – wenn wir diese Methode aufrufen, können wir entweder eine Variable von TYPE REF TO cl_super
oder eine beliebige der Unterklassen übergeben, da jede Instanz von CL_SUB1
eine CL_SUPER
-Instanz ist. Dies gilt
auch für Unterklassen, von denen der Ersteller der ursprünglichen Klassen nichts weiß – zum Beispiel für alle
Kundenimplementierungen, die das bestehende Framework erweitern.

EXPORTING
Für Methoden, die EXPORTING
-Parameter bereitstellen, gilt ein etwas anderes Muster:
METHODS bar
EXPORTING er_object TYPE REF TO cl_super.
...
DATA: lr_super TYPE REF TO cl_super,
lr_root TYPE REF TO cl_root,
lr_object TYPE REF TO object.
...
lr_foo->bar( IMPORTING er_object = lr_super ).
lr_foo->bar( IMPORTING er_object = lr_root ).
lr_foo->bar( IMPORTING er_object = lr_object ).
In diesem Fall ist der statische Typ der Variablen, die das exportierte Objekt empfängt, von Bedeutung: Es kann sich um
einen TYPE REF TO cl_super
oder eine seiner Oberklassen handeln.

CHANGING
Sie haben es vielleicht schon erraten – für einen CHANGING
-Parameter müssen Sie die Einschränkungen beachten, die für
IMPORTING
-Parameter gelten, sowie die, die für EXPORTING
-Parameter gelten – mit anderen Worten, Sie können nur den
genauen Typ verwenden, der von der Methode angegeben wird. Sie können keinen Supertyp verwenden, da dies gegen die
Anforderung verstoßen würde, dass jedes an die Methode übergebene Objekt mindestens der durch CL_SUPER
vorgegebenen
Struktur entspricht, und Sie können auch keinen Subtyp verwenden, da die Methode nicht garantiert, dass sie etwas
Spezifischeres als einen Verweis auf CL_SUPER
zurückgibt.

Warum überhaupt CHANGING?
Jetzt lehne ich mich in diesem Fall vielleicht ein wenig aus dem Fenster, aber ich denke, dass in vielen Fällen, in
denen CHANGING
-Parameter für Objektreferenzen verwendet werden, diese eigentlich unnötig sind und wahrscheinlich nur
aufgrund eines Missverständnisses verwendet werden. Nur um es klarzustellen: Um den Zustands eines Objekts zu ändern,
muss es nicht als CHANGING
-Parameter übergeben werden. Das gilt auch das Gegenteil: Um den Zustand eines Objekts
für die Methode, an die Sie es übergeben, unveränderlich zu machen, reicht es nicht aus, es als „IMPORTING“-Parameter zu
deklarieren.
Lassen Sie uns dies etwas näher untersuchen.
METHODs print
IMPORTING ir_person TYPE REF TO cl_person.
...
METHOD print.
DATA: l_name TYPE string,
lr_nobody TYPE REF TO cl_person.
l_name = ir_person-> get_name( ).
WRITE: / 'Name:', l_name.
* Die Referenz selbst zu ändern ist verboten:
CREATE OBJECT lr_nobody
EXPORTING i_name = 'Ann Onymous'.
ir_person = lr_nobody. " <--- SYNTAX ERROR
* aber das Ändern des Status des übergebenen Objekts ist erlaubt:
ir_person->set_name( 'John Doe' ).
ENDMETHOD.
Das Ausmaß des Problems
Aus Neugier habe ich ein zufälliges System überprüft und über 12.000 Parameter geschützt‚er und öffentlicher Methoden
gefunden, die CHANGING
-Referenzparameter verwenden – also habe ich tiefer gegraben. Folgendes habe ich gefunden:
