Object References

References have been introduced in ABAP in conjunction with ABAP Objects. Distinction is made between data references and object references. Object references are used as pointers to objects. Object references (the values of reference variables) are the only way to access the components of an object in an ABAP program. You can use references to access attributes and methods, but not events.

Reference Variables

Reference variables contain references. A reference variable f is either initial or contains a reference to an existing object. In the latter case, the logical expression f IS BOUND is true. A reference variable that points to an object contains the 'address' of the object. Objects and their components can only be addressed through references.

In ABAP, reference variables are treated like other data objects with an elementary data type. This means that a reference variable need not be a standalone field, but can also be a component of complex data objects, for example, structures and internal tables.

Data Types for References

ABAP contains a special data type for references, comparable to the special data types for structures or internal tables. The full data type is defined when you declare the variable in the ABAP program. It determines how the program handles the value of the variable (the object reference itself).

There are two kinds of references:

Class Reference

You define class references in full using the addition TYPE REF TO class of the TYPES or DATA statement, where class is a class that is recognized in the declaration part of the program.

Reference variables of this type are called class reference variables, or just class references.

A class reference cref allows users to use the form cref->comp to access all of the visible components comp of the object to which the object reference points, that is, usually all public components of the class.

Interface References

You define interface references in full using the TYPE REF TO intf addition of the TYPES or DATA statement, where intf is an interface that has already been declared in the program. References of this kind are called interface reference variables, or interface references.

With an interface reference iref, you can use the form iref->icomp to access all of the visible interface components icomp of the object to which the reference points. Interface components are those components of an object that are declared by implementing the interface in the class.

As well as in declarations, you can use the TYPE REF TO ... addition in all other statements in which type specifications are possible, for example, to specify the types of interface parameters in procedures.

Special References

Two specific references exist in a class, the self-reference ME and the pseudo reference SUPER.

The self-reference is used to address an object's own components explicitly. In the instance methods of a class, ME is a predefined local reference variable with the type of its class whose content points to its own instance. It can be specified to address its own component but does not have to be specified. It can also be assigned to other reference variables or passed to methods.

The pseudo reference SUPER is used to call the hidden method in a redefined instance method in connection with inheritance. The pseudo reference is not a genuine reference because an instance of a subclass cannot have an associated superclass instance, that is, no corresponding reference variable. The pseudo reference SUPER is the syntactical expression for a method call in a superclass.

Initializing Reference Variables

Like other variables, reference variables are initialized using the statement CLEAR. The initial value of a reference variable is a reference which does not point to any object.

Assigning References - Narrowing Cast

You can assign references between reference variables using the MOVE statement. This means that the references in several references variables can point to the same object (sharing). If you make assignments between reference variables, the dynamic type of the source variable must be compatible with the static type of the target variable. The dynamic type is the class of the object to which the reference in a reference variable points. The static type is the type (class or interface) with which the reference variable has been typed. The static type of the target variable must always be more generic than the dynamic type of the source variable.

The syntax check in the program can only compare the static type of the source variable with the static type of the target variable. When you assign reference variables using the MOVE statement or the assignment operator (=), the system performs this comparison. You can only make assignments that fulfill the above requirements for static types (narrowing cast). The same applies when passing parameters to procedures. Assignments are always possible if the static type of the target variable can address the same number of components as the static type of the source variable or fewer components:

If cref1 and cref2 are class references, and iref1 and iref2 are interface references, the following assignments can be checked statically:

cref1 = cref2
Both class references must refer to the same class, or the class of cref1 is a superclass of the class of cref2. The class of cref1 can always be OBJECT because Object is the superclass for all classes in ABAP Objects.
iref1 = iref2
Both interface references must refer to the same interface, or the interface of iref2 must be a nested interface, including the interface of iref1 as a component.
iref1 = cref1
The class of class reference cref1 or one of its superclasses must implement the interface of interface reference iref1. The implementation can be performed directly or using a nested interface, which includes the interface of iref1 as a component.
cref1 = iref1
The class of cref1 must be OBJECT, that is, the reference variable cref1 must have the type REF TO OBJECT.

OBJECT is a predefined empty class and the root node for all inheritance trees in ABAP Objects. This class has no components and has a similar function for reference variables as the data type ANY has for normal variables. Reference variables with the type OBJECT can be used as containers for passing references. They cannot be used for static access to objects; however, dynamic access is possible.

Assigning References - Widening Cast

If a static type check is not possible, or whenever you want the type check to take place at runtime, use the MOVE ... ?TO statement or the casting operator (?=). The casting operator replaces the assignment operator (=). When you use either of these options, there is no static type check. Instead, the system checks at runtime whether the object reference of the source variable points to an object to which the object reference in the target variable may also point (widening cast). The dynamic type of the source variable is compared with the static type of the target variable. The system assigns the reference if this is possible, otherwise, it generates the exception CX_SY_MOVE_CAST_ERROR which can be handled.

The syntax requires you to use a widening cast in all cases that are not listed above under static type checks. For example:

cref1 ?= iref1
Assigning an interface refernce to a class reference. For the assignment to be successful, the object to which iref1 points must belong to the same class as the type of the class variable cref1 or to an apppropriate subclass.

Object References as Actual Parameters

You can pass object references as actual parameters to procedures (methods, function modules, and subroutines) by specifying object reference variables. As far as typed formal parameters are concerned, note that you may only pass actual parameters of exactly the same type if the formal parameter can be changed in the procedure. This applies also to EXPORTING and CHANGING parameters of function modules and methods, parameters in subroutines passed by reference and CHANGING parameters in subroutines passed by value.

Passing actual parameters to formal parameters which is equivalent to a narrowing cast, such as passing a class reference variable to a formal parameter which is typed with reference to an interface of the class or one of its superclasses, is not possible if the parameter can be changed in the procedure.

The reason is that a reference could be assigned to the actual parameter in the procedure which is incompatible with its static type, such as a reference to any other class that implements the same interface or a referene to a subclass in another node of the inheritance tree.

Assigning Object References to Field Symbols

When you assign object references to typed field symbols, the same applies as when you pass a reference to typed formal parameters: The types must be identical. Otherwise, incompatibilities between dynamic and static types may occur. For example, if you assign two class reference variables of different classes implementing the same interface one after the other to the same field symbol, an inconsistent state results.