Classes, their instances (objects), and
access to objects using reference variables form the basics of ABAP
Objects. These means already allow you to model typical business
applications, such as customers, orders, order items, invoices, and so
on, using objects, and to implement solutions using ABAP Objects.
However, it is often necessary for similar
classes to provide similar functions that are coded differently in each
class but which should provide a uniform point of contact for the user.
For example, you might have two similar classes, savings account and
check account, both of which have a method for calculating end of year
charges. The interfaces and names of the methods are the same, but the
actual implementation is different. The user of the classes and their
instances must also be able to run the end of year method for all
accounts, without having to worry about the actual type of each
individual account.
ABAP Objects makes this possible by using
interfaces. Interfaces are independent structures that you can implement
in a class to extend the scope of that class. The class-specific scope
of a class is defined by its components and visibility sections. For
example, the public components of a class define its public scope, since
all of its attributes and method parameters can be addressed by all
users. The protected components of a class define its scope with regard
to its subclasses.
Interfaces extend the scope of a class by
adding their own components to its public section. This allows users to
address different classes via a universal point of contact. Interfaces,
along with inheritance, provide one of the pillars of polymorphism,
since they allow a single method within an interface to behave
differently in different classes.
Defining
Interfaces
Like classes, you can define interfaces
either globally in the R/3 Repository or locally in an ABAP program. For
information about how to define local interfaces, refer to the
class builder s
ection of the ABAP Workbench
Tools documentation. The definition of a local interface <intf> is
enclosed in the statements:
INTERFACE <intf>.
�
ENDINTERFACE.
The definition contains the declaration
for all components (attributes, methods, events) of the interface. You
can define the same components in an interface as in a class. The
components of interfaces do not have to be assigned individually to a
visibility section, since they automatically belong to the public
section of the class in which the interface is implemented. Interfaces
do not have an implementation part, since their methods are implemented
in the class that implements the interface.
Implementing
Interfaces
Unlike classes, interfaces do not have
instances. Instead, interfaces are implemented by classes. To implement
an interface in a class, use the statement
INTERFACES <intf>.
in the declaration part of the class.
This statement may only appear in the public section of the class.
When you implement an interface in a
class, the components of the interface are added to the other components
in the public section. A component <icomp> of an interface <intf> can be
addressed as though it were a member of the class under the name
<intf~icomp>.
The class must implement the methods of
all interfaces implemented in it. The implementation part of the class
must contain a method implementation for each interface method <imeth>:
METHOD <intf~imeth>.
�
ENDMETHOD.
Interfaces can be implemented by
different classes. Each of these classes is extended by the same set of
components. However, the methods of the interface can be implemented
differently in each class.
Interfaces allow you to use different
classes in a uniform way using interface references (polymorphism). For
example, interfaces that are implemented in different classes extend the
public scope of each class by the same set of components. If a class
does not have any class-specific public components, the interfaces
define the entire public face of the class.
Interface
References
Reference variables allow you to access
objects . Instead of creating reference variables with reference to a
class, you can also define them with reference to an interface. This
kind of reference variable can contain references to objects of classes
that implement the corresponding interface.
To define an interface reference, use the
addition TYPE REF TO <intf> in the TYPES or DATA statement. <intf> must
be an interface that has been declared to the program before the actual
reference declaration occurs. A reference variable with the type
interface reference is called a interface reference variable, or
interface reference for short.
An interface reference <iref> allows a
user to use the form <iref>-><icomp> to address all visible interface
components <icomp> of the object to which the object reference is
pointing. It allows the user to access all of the components of the
object that were added to its definition by the implementation of the
interface.
Addressing Objects Using
Interface References
To create an object of the class <class>,
you must first have declared a reference variable <cref> with reference
to the class. If the class <class> implements an interface <intf>, you
can use the following assignment between the class reference variable
<cref> and an interface reference <iref> to make the interface reference
in <iref> point to the same object as the class reference in <cref>:
<iref> = <cref>
If the interface <intf> contains an
instance attribute <attr> and an instance method <meth>, you can address
the interface components as follows:
Using the class reference
variable <cref>:
To access an attribute <attr>: <cref>-><intf~attr>
To call a method <meth>:
CALL METHOD <cref>-><intf~meth>
Using the interface reference
variable <iref>:
To access an attribute <attr>: <
iref>-><attr>
To call a method <meth>:
CALL METHOD <iref>-><meth>
As far as the static components of
interfaces are concerned, you can only use the interface name to access
constants:
Addressing a constant <const>: <
intf>=><const>
For all other static components of an
interface, you can only use object references or the class <class> that
implements the interface:
Addressing a static attribute <attr>: <
class>=><intf~attr>
Calling a static method <meth>:
CALL METHOD <class>=><intf~meth>
Assignment Using Interface
References - Casting
Like class references, you can assign
interface references to different reference variables. You can also make
assignments between class reference variables and interface reference
variables. When you use the MOVE statement or the assignment operator
(=) to assign reference variables, the system must be able to recognize
in the syntax check whether an assignment is possible.
Suppose we have a class reference <cref>
and interface references <iref>, <iref1>, and <iref2>. The following
assignments with interface references can be checked statically:
<iref1> = <iref2>
Both interface references must refer to
the same interface, or the interface of <iref1> must contain the
interface <iref2> as a component.
<iref> = <cref>
The class of the class reference <cref>
must implement the interface of the interface reference <iref>.
<cref> = <iref>
The class of <cref> must be the
predefined empty class OBJECT.
In all other cases, you would have to work
with the statement MOVE �? TO or the casting operator
(?=). The casting operator replaces the assignment operator (=). In the
MOVE� ? TO statement, or when you use the casting operator, there is no
static type check. Instead, the system checks at runtime
whether the object reference in the source variable points to an object
to which the object reference in the target variable can also point. If
the assignment is possible, the system makes it, otherwise, the
catchable runtime error MOVE_CAST_ERROR occurs.
You must always use casting for assigning
an interface reference to a class reference if <cref> does not refer to
the predefined empty class OBJECT:
<cref> ?= <iref>
For the casting to be successful, the
object to which <iref> points must be an object of the same class as the
type of the class variable <cref>.