Interfaces can be composed. An interface can include one or more interfaces as components, which can contain interfaces themselves. An interface including another interface is called a compound interface. An interface composed within an interface is called a component interface. An interface that does not contain any compound interfaces is called an elementary interface.
All interface components of a compound interface have the same level. If a compound interface i3 contains another compound interface i2, its interface component i1 becomes interface component of i3. A compound interface includes each interface component exactly once. A component interface exists only once even if it is used again as a component of another component interface.
The statement INTERFACES is used for composing interfaces within an interface definition:
INTERFACE i3.Here the interface i3 consists of its components and the interfaces i1 and i2. In the compound interface the components of the component interfaces are visible using the interface component selector (~). Within the above definition of i3, expressions such as i1~comp or i2~comp are possible. However, you can define your own names using the ALIASES statement.
Within interface definitions, the statement ALIASES can be used to assign
alias names to the components of component interfaces, and therefore make those nested to a depth greater
than one level visible within the interface definition.
INTERFACE
i2.
INTERFACES i1.
ALIASES
alias21 FOR i1~comp1.
ENDINTERFACE.
INTERFACE i3.
INTERFACES
i2.
ALIASES alias31 FOR i2~alias21.
ALIASES alias32 FOR i2~comp2.
ENDINTERFACE.
Interface references typed with reference to a compound interface can be assigned to interface references
typed with reference to one of the component interfaces (narrowing cast). The latter can be used to
address the components of the component interfaces. The opposite case cannot be checked statically and
must take place with the casting operator (?=) (widening Cast).
INTERFACE i1.
DATA
comp1.
ENDINTERFACE.
INTERFACE
i2.
DATA comp2.
INTERFACES
i1.
ENDINTERFACE.
INTERFACE
i3.
INTERFACES i2.
ENDINTERFACE.
DATA: iref1 TYPE REF TO i1,
iref2
TYPE REF TO i2,
iref3
TYPE REF TO i3.
iref2 = iref3.
iref1
= iref2.
* recommended access:
... iref1->comp1 ...
... iref2->comp2
...
* non-recommended access:
... iref2->i1~comp1 ...
... iref3->i2~comp2 ...
When a nested interface is implemented in a class, all associated interfaces are implemented in the
class at the same level irrespective of their nesting hierarchy and the class must
implement all methods only once.
INTERFACE i1.
DATA comp1.
METHODS
meth1.
ENDINTERFACE.
INTERFACE
i2.
DATA comp2.
INTERFACES
i1.
ENDINTERFACE.
INTERFACE
i3.
DATA comp3.
INTERFACES
i2.
ENDINTERFACE.
CLASS
class DEFINITION.
PUBLIC SECTION.
INTERFACES i3.
ENDCLASS.
CLASS class IMPLEMENTATION.
METHOD i1~meth.
...
ENDMETHOD.
ENDCLASS.
DATA:
cref TYPE REF TO class.
DATA iref1 TYPE REF TO i1.
DATA iref2 TYPE REF TO i2.
DATA iref3 TYPE REF TO
i3.
iref1 = iref2 = iref3 = cref.
* recommended access:
... iref1->comp1
...
... iref2->comp2 ...
... iref3->comp3 ...
* non recommended
access:
... cref->i1~comp1 ...
... cref->i2~comp2 ...
... cref->i3~comp3
...
... iref3->i1~comp1 ...
... iref3->i2~comp2 ...
... iref2->i1~comp1 ...
You can always assign reference variables using narrowing cast. Class references to classes that implement a compound interface can be assigned to all interface references that are typed with reference to an associated interface component. In the class, the interface references know only the components of their respective interfaces. Similarly, interface references that are typed using one compound interface can be assigned to all interface reference variables that are typed with one of these component interfaces. It is possible to access components using the interface component selector, but this is not recommended. Compound expressions such as cref->i3~i2~comp2 or cref->i3~i2~i3~comp3 are not possible.