Files
abap-cheat-sheets/04_ABAP_Object_Orientation.md
Daniel Reger 75587a904b Initial commit
2022-12-05 11:03:16 +01:00

1214 lines
59 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<a name="top"></a>
# ABAP Object Orientation
> **💡 Note**<br>
> This cheat sheet provides an overview on selected syntax options and concepts related to ABAP object orientation. It is supported by code snippets and an executable example. They are **not** suitable as role models for object-oriented design. Their primary focus is on the syntax and functionality. For more details, refer to the respective topics in the ABAP Keyword Documentation. Find an overview in the topic [ABAP Objects - Overview](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap_objects_oview.htm).
- [ABAP Object Orientation](#abap-object-orientation)
- [Classes and Objects](#classes-and-objects)
- [Creating Classes](#creating-classes)
- [Creating a Local Class](#creating-a-local-class)
- [Creating a Global Class](#creating-a-global-class)
- [Visibility of Components](#visibility-of-components)
- [Creating the Visibility Sections](#creating-the-visibility-sections)
- [Defining Components](#defining-components)
- [Working with Objects and Components](#working-with-objects-and-components)
- [Notes on Inheritance](#notes-on-inheritance)
- [Notes on Polymorphism and Casting](#notes-on-polymorphism-and-casting)
- [Working with Interfaces](#working-with-interfaces)
- [Further Concepts](#further-concepts)
- [Factory Methods](#factory-methods)
- [Friendship](#friendship)
- [Events](#events)
- [Executable Example](#executable-example)
## Classes and Objects
Object-oriented programming in ABAP means dealing with
[classes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_glosry.htm "Glossary Entry")
and
[objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_glosry.htm "Glossary Entry").
Objects ...
- are
[instances](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_glosry.htm "Glossary Entry")
of a
[type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentype_glosry.htm "Glossary Entry").
In this context, they are instances of a
[class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_glosry.htm "Glossary Entry").
The terms object and instance are used synonymously.
- exist in the [internal
session](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninternal_session_glosry.htm "Glossary Entry")
of an [ABAP
program](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm "Glossary Entry")
Classes ...
- are templates for objects, i. e. they determine the appearance of
all instances of a class. All instances are created based on this
template (this is what is called
[instantiation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstantiation_glosry.htm "Glossary Entry")).
- If, for example, a vehicle represents a class, then the
instances of the class `vehicle` have the same setup.
That means they all share the same kind of data like the brand,
model and color or the same functionality like the acceleration.
However, the values are different from instance to instance.
Hence, an instance has a unique identity. For example, one
instance is a red sedan of brand A having a certain
acceleration; another instance is a black SUV of brand B and so
on. You create an object (or instance respectively) that stands
for an actual vehicle to work with in your ABAP program.
- Basically, you might create any number of objects that are based
on a class.
- contain
[components](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomponent_glosry.htm "Glossary Entry"):
- [Attributes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenattribute_glosry.htm "Glossary Entry")
of the objects (the data declarations)
- [Methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmethod_glosry.htm "Glossary Entry")
that typically operate on this data
- [Events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenevent_glosry.htm "Glossary Entry")
<p align="right">(<a href="#top">back to top</a>)</p>
### Creating Classes
You can either create local or global classes:
<table>
<tr>
<td><a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlocal_class_glosry.htm">Local classes</a></td>
<td><ul><li>can be defined within an ABAP program (or a <a href="https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenccimp_glosry.htm">CCIMP include</a> respectively)</li><li>can only be used in the program (or global class/CCIMP include respectively) in which the class is defined</li></ul></td>
</tr>
<tr>
<td><a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_class_glosry.htm">Global
classes</a></td>
<td><ul><li>are defined as global type; hence, they can be used by all ABAP programs or global classes respectively since they are globally visible</li><li>are declared in <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_pool_glosry.htm">class pools</a></li></ul> </td>
</tr>
</table>
> **💡 Note**<br>
> - Regarding the names of global and local classes and usage of classes in ABAP programs when, for example, calling methods, the system searches for a local class with the specific name at first. Then, if a local class with that name is not found, the systems searches for a global class.
> - The class design must be done with care. If a class is only used in one program (or class), choosing a local class is enough. However, global
classes must be prepared to be used anywhere. A later change of that class, especially regarding the visibility of components (see
further down) or the data types of attributes that are used in other programs might cause problems.
> - Apart from ADT, global classes can also be created in the ABAP Workbench (`SE80`) or with transaction `SE24` in on-premise systems.
The basic structure of classes consists of a declaration and an implementation part that are both introduced by `CLASS` and ended by `ENDCLASS`.
#### Creating a Local Class
``` abap
CLASS local_class DEFINITION.
    
"Here go the declaration for all components and visibility sections.
    "You should place the declaration at the beginning of the program.
ENDCLASS.
CLASS local_class IMPLEMENTATION.
    "Here go the method implementations.
    "Only required if you declare methods in the DEFINITION part.
ENDCLASS.
```
#### Creating a Global Class
The code snippet shows a basic skeleton of a global class. There are [further
additions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_options.htm)
possible.
``` abap
CLASS global_class DEFINITION
  PUBLIC   "Makes the class a global class in the class library.
FINAL     "Means that no subclasses can be derived from this class.
  CREATE PUBLIC. "This class can be instantiated anywhere it is visible.
    ...
    "Here go the declaration for all components and visibility sections.
ENDCLASS.
CLASS global_class IMPLEMENTATION.
    "Here go the method implementations.
    "Only required if you declare methods in the DEFINITION part.
ENDCLASS.
```
> **💡 Note**<br>
> The addition `... CREATE PROTECTED.` of the class declaration part means that the class can only be instantiated in methods of its
[subclasses](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubclass_glosry.htm "Glossary Entry"),
of the class itself, and of its
[friends](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfriend_glosry.htm "Glossary Entry").
The addition `... CREATE PRIVATE` means that the class can only
be instantiated in methods of the class itself or of its friends. Hence,
it cannot be instantiated as an inherited component of subclasses.
<p align="right">(<a href="#top">back to top</a>)</p>
### Visibility of Components
In the class declaration part, you must specify (at least one of the)
[visibility
sections](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenvisibility_section_glosry.htm "Glossary Entry")
to determine how to interact with the class. For example, you want to
hide and thus disallow the usage of certain data. The visibility
sections are as follows:
<table>
<tr>
<td><pre>PUBLIC.</pre></td>
<td>Components declared in this section can be accessed from within the class and from outside including subclasses.</td>
</tr>
<tr>
<td><pre>PROTECTED.</pre></td>
<td>Components declared in this section can be
accessed from within the class and from <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubclass_glosry.htm">subclasses</a> and <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfriend_glosry.htm">friends</a>
- topics related to <a href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninheritance_glosry.htm">inheritance</a>.</td>
</tr>
<tr>
<td><pre>PRIVATE.</pre></td>
<td>Components declared in this section can only be accessed from within the class in which they are declared and its friends.</td>
</tr>
</table>
#### Creating the Visibility Sections
At least one section must be specified.
``` abap
CLASS local_class DEFINITION.
    PUBLIC.
      "Here go the components.
    PROTECTED.
      "Here go the components.
    PRIVATE.
      "Here go the components.
ENDCLASS.
```
<p align="right">(<a href="#top">back to top</a>)</p>
### Defining Components
All components - attributes (using `TYPES`, `DATA`,
`CLASS-DATA`, and `CONSTANTS` for data types and data
objects), methods (using `METHODS` and `CLASS-METHODS`),
events `EVENTS` and `CLASS-EVENTS` as well as interfaces - are declared in the declaration part of the class. There, they must be
assigned to a visibility section.
Regarding, for example, `DATA` and `CLASS-DATA`, two
kind of components are to be distinguished:
- [Instance
components](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_component_glosry.htm "Glossary Entry"):
Components that exist separately for each instance and can only be
accessed in instances of a class.
- [Static
components](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_component_glosry.htm "Glossary Entry"):
Components that are not specific for instances. They exist only once
per class and can be accessed using the name of the class.
**Attributes**
- The attributes of a class mean the data objects declared within a
class (or interface).
- [Static
attributes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_attribute_glosry.htm "Glossary Entry")
(`CLASS-DATA`): Their content is independent of instances of
a class and, thus, valid for all instances. As shown further down,
static attributes can be accessed by using the class name without a
prior creation of an instance. Note that changing an instance
attribute means the change is visible in all instances.
- [Instance
attributes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_attribute_glosry.htm "Glossary Entry")
(`DATA`): Determine the instance-dependent state. The data
is only valid in the context of an instance. As shown further down,
instance attributes can only be accessed via an [object reference
variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_refer_variable_glosry.htm "Glossary Entry").
> **💡 Note**<br>
> You can declare static attributes that should not be
changed using
[`CONSTANTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapconstants.htm)
statements. You specify the values for the constants when you declare
them. Furthermore, the addition
[`READ-ONLY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_options&sap-language=EN&sap-client=000&version=X&anchor=!ABAP_ADDITION_2@2@&tree=X)
can be used in the public visibility section as a means of securing data
objects against undesired changes from outside. A change is only
possible via the methods of the class or it subclasses.
Declaring attributes in visibility sections. In the snippet below, all attributes are declared in the `PUBLIC.` section of a local class.
``` abap
CLASS local_class DEFINITION.
    PUBLIC.
      TYPES: some_type TYPE c LENGTH 3.             "Type declaration
      DATA: inst_number TYPE i,                     "Instance attributes
            inst_string TYPE string,
            dobj_r_only TYPE c LENGTH 5 READ-ONLY. "Read-only attribute
      CLASS-DATA: stat_number TYPE i,           "Static attributes
                  stat_char   TYPE c LENGTH 3.
      CONSTANTS: const_num TYPE i VALUE 123.   "Non-changeable constant
    PROTECTED.
      "Here go more attributes.
    PRIVATE.
      "Here go more attributes.
ENDCLASS.
CLASS local_class IMPLEMENTATION.
      "Here go all method implementations.
ENDCLASS.
```
<p align="right">(<a href="#top">back to top</a>)</p>
**Methods**
- Are internal
[procedures](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprocedure_glosry.htm "Glossary Entry")
determining the behavior of the class.
- Can access all of the attributes of a class and, if not defined
otherwise, change their content.
- Have a [parameter
interface](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenparameter_interface_glosry.htm "Glossary Entry")
(also known as
[signature](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensignature_glosry.htm "Glossary Entry"))
with which methods can get values when being called and pass values
back to the caller.
- [Static
methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_method_glosry.htm "Glossary Entry")
can only access static attributes of a class and trigger static
events. You declare them using `CLASS-METHODS` statements in
a visibility section.
- [Instance
methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_method_glosry.htm "Glossary Entry")
can access all of the attributes of a class and trigger all events.
You declare them using `CLASS` statements in a visibility
section. Since instance methods are bound to instances, an instance
of the class must first be created before using them.
**Parameter Interface**
In the simplest form, methods can have no parameter at all. Apart from that, methods can be defined with the following parameters:
| Addition | Details |
|---|---|
|`IMPORTING`|Defines one or multiple parameters that are imported (or input) by the method (e. g. from another object or an ABAP program) with which the method can work. |
|`EXPORTING`|Defines one or multiple parameters that are exported (or output) by the method (e. g. to another object or an ABAP program). |
|`CHANGING`|Defines one or multiple parameters that can be both imported and exported. |
|`RETURNING`|Only one `RETURNING` parameter can be defined for methods. These methods are called functional methods. Like `EXPORTING` parameters, `RETURNING` parameters pass back values (note that the formal parameters of returning parameters must be passed by value), i. e. they are output parameters. The difference is that there can be multiple `EXPORTING` parameters in a method. However, `RETURNING` parameters simplify the syntax if there is only one value to be passed back. It shortens the method call and enables method chaining. Furthermore, functional methods can, for example, be used in arithmetic or logical expressions. In case of standalone method calls, the returned value can be accessed using the addition `RECEIVING`. |
|`RAISING` | Used to declare the class-based exceptions to handle errors. |
> **💡 Note**<br>
> - You may find the addition `EXCEPTIONS` especially in definitions of older classes. They are for non-class-based exceptions. The exceptions are based on the system field `sy-subrc` and raised according to setting this field. You can then check the value of `sy-subrc` and act accordingly. This addition should not be used in ABAP for Cloud Development.
> - [Formal
parameter](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenformal_parameter_glosry.htm "Glossary Entry")
versus [actual
parameter](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenactual_parameter_glosry.htm "Glossary Entry"):
You define method parameters by specifying a name with a type which
can be a
[generic](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abengeneric_data_type_glosry.htm "Glossary Entry")
or
[complete](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomplete_data_type_glosry.htm "Glossary Entry")
type. This formal parameter includes the specification of how the
value passing should happen. Parameters can be [passed by
reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpass_by_reference_glosry.htm "Glossary Entry")
(`... REFERENCE(param) ...`; note that just specifying the
parameter name `... param ...` - as a shorter syntax -
means passing by reference by default) or [by
value](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpass_by_value_glosry.htm "Glossary Entry")
(`... VALUE(param) ...`). The actual parameter represents
the data object whose content is passed to or copied from a formal
parameter as an argument when a procedure is called. If
pass-by-reference is used, a local data object is not created for
the actual parameter. Instead, the procedure is given a
[reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_glosry.htm "Glossary Entry")
to the actual parameter during the call and works with the actual
parameter itself. Note that parameters that are input and passed by
reference cannot be modified in the procedure. However, the use of a
reference is beneficial regarding the performance compared to
creating a local data object.
>- Parameters can be defined as optional using the
[`OPTIONAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_parameters&sap-language=EN&sap-client=000&version=X&anchor=!ABAP_ONE_ADD@1@&tree=X)
addition. In doing so, it is not mandatory to pass an actual
parameter. The
[`DEFAULT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_parameters&sap-language=EN&sap-client=000&version=X&anchor=!ABAP_ONE_ADD@1@&tree=X)
addition also makes the passing of an actual parameter optional.
However, when using this addition, as the name implies, a default
value is set.
<p align="right">(<a href="#top">back to top</a>)</p>
**Constructors**
- [Constructors](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_glosry.htm "Glossary Entry")
are special methods that are usually used for setting a defined
initial state of objects, e. g. for setting a particular starting
value for attributes in an object.
- A class can only have one [instance
constructor](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_constructor_glosry.htm "Glossary Entry")
and one [static
constructor](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_constructor_glosry.htm "Glossary Entry").
- Constructors always exist implicitly in classes. However, their
declaration and use is optional. If they are declared explicitly,
they must consequently be implemented. Note that they are always
called automatically even if not declared and implemented.
- Static constructor: Automatically called when calling a class for
the first time in an internal session. This constructor is declared
using the predefined name `class_constructor` as part of a
`CLASS-METHODS` statement in the public visibility section.
Static constructors cannot have any parameters.
- Instance constructor: Automatically called when a class is
instantiated and an object is created. The constructor is declared
using the predefined name `constructor` as part of a
`METHODS` statement. In contrast to local classes, instance
constructors must be declared in the public visibility section of
global classes. They can only have `IMPORTING` parameters
and exceptions. In case of exceptions, make sure that you use a
[`TRY ... ENDTRY.`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptry.htm)
block in the implementation since otherwise the instance is not
created if uncaught errors occur.
Example for method definitions: The following snippet shows
multiple method definitions in the public section. Most of the formal
parameters of the demo methods below are defined by just using the
parameter name. This means passing by reference (returning parameters
require to be passed by value).
``` abap
CLASS local_class DEFINITION.
    PUBLIC.
      METHODS: inst_meth1 IMPORTING a TYPE i   "instance methods
                          EXPORTING b TYPE i,
               inst_meth2 IMPORTING c TYPE string
               inst_meth2 IMPORTING d TYPE string
                          RETURNING VALUE(e) TYPE string,
               inst_meth3 IMPORTING f TYPE i
                          EXPORTING g TYPE i
                          CHANGING  h TYPE string_table
                          RETURNING VALUE(i) TYPE i
                          RAISING   cx_sy_zerodivide,
             constructor IMPORTING j TYPE i. "instance constructor with importing parameter
      CLASS-METHODS: stat_meth1 IMPORTING k TYPE i    "static methods
                                EXPORTING l TYPE i,
                     stat_meth2,         "no formal parameters
                     class_constructor,   "static constructor
                     "Formal parameter definitions
                     stat_meth3 IMPORTING VALUE(m) TYPE i "pass by value
                                          REFERENCE(n) TYPE i "pass by reference
                                          o TYPE i, "same as n
                     "OPTIONAL/DEFAULT additions
                     stat_meth4 IMPORTING p TYPE i DEFAULT 123
                                       q TYPE i OPTIONAL.
ENDCLASS.
CLASS local_class IMPLEMENTATION.
   METHOD inst_meth1.
      ...            "Here goes the method implementation.
   ENDMETHOD.
...                  "Note that all declared methods must be implemented.
ENDCLASS.
```
<p align="right">(<a href="#top">back to top</a>)</p>
## Working with Objects and Components
**Declaring reference variables**: To create an object, a
[reference
variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_variable_glosry.htm "Glossary Entry")
must be declared. Such an [object reference
variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_refer_variable_glosry.htm "Glossary Entry")
is also necessary for accessing objects and their components, i. e.
objects are not directly accessed but only via references that point to
those objects. This reference is stored in the reference variables.
``` abap
DATA: ref1 TYPE REF TO local_class,
      ref2 TYPE REF TO global_class,
      ref3 LIKE ref1.
```
**Creating objects**: You create an object by using the instance
operator
[`NEW`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_new.htm).
In doing so, a new instance of a class is created and the reference to
it is assigned to an object reference variable. The `#` sign
means that the type (`TYPE REF TO ...`) can be derived from the
context (in this case from the type of the reference variable). You can
also omit the explicit declaration of a reference variable by declaring
a new reference variable
[inline](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_inline.htm),
for example, using `DATA`. In this case, the name of the class
must be placed after `NEW` and before the first parenthesis. The `NEW` operator replaces the older
[`CREATE OBJECT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcreate_object.htm)
statements.
``` abap
ref1 = NEW #( ). "Type derived from already declared ref1
DATA(ref2) = NEW local_class( ). "Reference variable declared inline, explicit type
"(class) specification
"Old syntax. Do not use.
"CREATE OBJECT ref3. "Type derived from already declared ref3
```
**Assigning or copying reference variables**: To assign or copy
reference variables, use the [assignment
operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_operator_glosry.htm "Glossary Entry")
`=`. In the example below, both reference variables have the same
type.
``` abap
DATA: ref1 TYPE REF TO local_class,
      ref2 TYPE REF TO local_class.
ref1 = NEW #( ).
ref2 = ref1.
```
**Overwriting reference variables**: An [object
reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_reference_glosry.htm "Glossary Entry")
is overwritten when a new object is created with a reference variable
already pointing to an instance.
``` abap
ref1 = NEW #( ).
ref1 = NEW #( ).
```
**Keeping object references in internal tables**: If your use case is to retain the object references, for example, if you create a series of objects and you want to prevent object references to be overwritten when using the same reference variable, you can put the reference variables in internal tables. The following code shows that three objects are created with the same reference variable. The internal table includes all object references and, thus, their values are retained.
``` abap
DATA: ref TYPE REF TO local_class,
      itab TYPE TABLE OF REF TO local_class.
DO 3 TIMES.
  ref = NEW #( ).
  itab = VALUE #( BASE itab ( ref ) ). "Adding the reference to itab
ENDDO.
```
**Clearing object references**: Use
[`CLEAR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclear.htm)
statements to explicitly clear a reference variable.
```
CLEAR ref.
```
> **💡 Note**<br>
> Since objects use up space in the memory, they should be
cleared if they are no longer needed. The [garbage
collector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abengarbage_collector_glosry.htm "Glossary Entry")
takes over this task automatically, i. e. all objects without any
reference are cleared and the memory space is released.
**Accessing attributes**: Instance attributes are accessed using
the [object component
selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_component_select_glosry.htm "Glossary Entry")
`->` via a reference variable. Visible static attributes are
accessed using the [class component
selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_component_select_glosry.htm "Glossary Entry")
`=>` via the class name. You can also declare data objects and
types by referring to the static attributes.
``` abap
"Accessing instance attribute via a reference variable
... ref->some_attribute ...
"Accessing static attributes via the class name
... local_class=>static_attribute ...
"Without the class name only within the class
... static_attribute ...
"Type and data object declarations
TYPES some_type LIKE local_class=>some_attribute.
DATA dobj1      TYPE local_class=>some_type.
DATA dobj2      LIKE local_class=>some_attribute.
```
**Calling methods**: Similar to accessing attributes, instance
methods are called using `->` via a reference variable. Static
methods are called using `=>` via the class name. When used
within the class in which it is declared, the static method can also be
called without `class_name=>...`. You might also see method
calls with [`CALL METHOD`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcall_method_static.htm)
statements which are not used here (however, these statements are the
only option in the context of dynamic programming.
When methods are called, the parameters must be specified within the
parentheses.
Examples for instance method calls and static method calls:
``` abap
"Calling instance methods via reference variable
ref->inst_meth( ... ).
"Calling static methods via/without the class name
class_name=>stat_meth( ... ).
"Only within the program in which it is declared.
stat_meth( ... ).  
"Calling (static) methdod having no parameter
class_name=>stat_meth( ).
"Calling (static) methods having a single importing parameter:
"Note that in the method call, the caller exports values to the
"method having importing parameters defined; hence, the ABAP word
"EXPORTING is relevant. The three following method calls are the same
"Explicit use of EXPORTING.
class_name=>meth( EXPORTING a = b ).
"Only importing parameters in the signature: explicit EXPORTING not needed
class_name=>meth( a = b ).
"Only a single value must be passed: parameter name (a) and EXPORTING not needed
stat_meth( b ).
"Calling (static) methods having importing/exporting parameters
"Parameters must be specified if they are not marked as optional
class_name=>meth( EXPORTING a = b c = d "a/c: importing parameters
                  IMPORTING e = f ). "e: exporting parameter
"If f is not yet available, you could also declare it inline.
class_name=>meth( EXPORTING a = b c = d
                  IMPORTING e = DATA(f) ). "f receives type of e
"Calling (static) methods having a changing parameter;
"should be reserved for changing an existing local variable and value
DATA h TYPE i VALUE 123.
class_name=>meth( CHANGING g = h ).
"Calling (static) methods having a returning parameter.
"Basically, they do the same as methods with exporting parameters
"but they are way more versatile and you save lines of code.
"They do not need temporary variables.
"In the example, the return value is stored in a variable declared inline.
"i and k are importing parameters
DATA(result) = class_name=>meth( i = j k = l )
"They can be used with other statements, e. g. logical expressions.
IF class_name=>meth( i = j k = l ) > 100.
  ...
ENDIF.
"They enable method chaining.
"The example shows a method to create random integer values.
"The methods have a returning parameter.
DATA(random_no) = cl_abap_random_int=>create( )->get_next( ).
"Receiving parameter: Available in methods defined with a returning parameter;
"used in standalone method calls only.
"In the snippet, m is the returning parameter; n stores the result.
class_name=>meth( EXPORTING i = j k = l RECEIVING m = DATA(n) ).
```
**Self-Reference me**
When implementing instance methods, you can make use of the implicitly available object reference variable `me` which is always available and points to the respective object itself. You can use it to refer to components of the instance of a particular class but it is not needed:
``` abap
... some_method( ... ) ...
... me->some_method( ... ) ...
```
However, if you want to access attributes of the particular class and these attributes have identical names as local attributes within the method, you can make use of `me` to access the attributes that are outside of the method and within the class. The following example demonstrates the use of `me` in a method implementation.
``` abap
METHOD me_ref.
DATA str TYPE string VALUE `Local string`.
DATA(local_string) = str.
"Assuming there is a variable str declared in the class declaration part.
DATA(other_string) = me->str.
ENDMETHOD.
```
<p align="right">(<a href="#top">back to top</a>)</p>
## Notes on Inheritance
- Concept: Deriving a new class (i. e. a
[subclass](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubclass_glosry.htm "Glossary Entry"))
from an existing one
([superclass](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensuperclass_glosry.htm "Glossary Entry"))
to share common components between classes. In doing so, you create
hierarchies of classes (an [inheritance
tree](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninheritance_tree_glosry.htm "Glossary Entry"))
while a superclass includes components that are shared by all
subclasses to provide a better structure for your code.
- Subclasses ...
- inherit all components from superclasses
- can access instance components from superclasses
- can be made more specific by declaring new components and
redefining instance methods (i. e. replacing the implementations
of inherited methods).
- can access static components but not redefine them.
- can only handle components in the `PROTECTED` and
`PUBLIC` section of superclasses.
- know their direct superclass but they do not know which classes
inherit from them. [Note:] Handle component definitions
and implementations in the superclass with great care since a
change might have undesired consequences for the subclasses.
- Components ...
- that are changed and added to subclasses are not visible to
superclasses, hence, these changes are only relevant for this
class itself and its subclasses.
- that are added should have a different name than those of the
superclass.
- A class ...
- can only inherit from one superclass, i. e. a subclass can only
have one superclass, however, a superclass can have any number
of subclasses.
- must enable derivation, i. e. classes cannot inherit from
classes that are specified with the addition
[`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_options&sap-language=EN&sap-client=000&version=X&anchor=!ABAP_ADDITION_4@4@&tree=X)
(e. g. `CLASS global_class DEFINITION PUBLIC FINAL CREATE PUBLIC. ...`).
<p align="right">(<a href="#top">back to top</a>)</p>
**Excursion: `ABSTRACT` and `FINAL`**
- A global class declared with the addition `FINAL` rules out
inheritance. The addition `FINAL` is also available for
[method
declarations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_abstract_final&sap-language=EN&sap-client=000&version=X&anchor=!ABAP_ADDITION_2@2@&tree=X)
in classes which rules out that such a method is redefined in
subclasses. In classes that are declared with `FINAL`, all
methods are implicitly final. Instance constructors are always final
by default.
- The addition
[`ABSTRACT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_abstract_final.htm)
is meant for abstract classes.
- The addition `ABSTRACT` enters the picture in the context of
abstract classes. These classes are used if you want to have a
template for subclasses and you do not need instances of such
classes. Instances are only possible for their subclasses. Instance
components of an abstract class can then be accessed via an
instantiated subclass. `ABSTRACT` is available for [class
declarations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_options&sap-language=EN&sap-client=000&version=X&anchor=!ABAP_ADDITION_3@3@&tree=X)
(e. g. `CLASS cl DEFINITION ABSTRACT. ...`) and [method
declarations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_abstract_final&sap-language=EN&sap-client=000&version=X&anchor=!ABAP_ADDITION_1@1@&tree=X)
(e. g. `METHODS meth ABSTRACT. ...`). Abstract methods can
only be declared within abstract classes. They are not implemented
in the implementation part of the abstract class. Instead, they must
be redefined in subclasses. Note that in abstract classes,
non-abstract methods can also be declared and that private methods
cannot be redefined, i. e. methods in this section cannot be
declared as abstract. See a high-level comparison of abstract
classes and interfaces further down.
<p align="right">(<a href="#top">back to top</a>)</p>
**Redefining Methods**
- The non-final method from the superclass that is redefined must be
specified in the declaration part of the subclass as follows:
`METHODS meth REDEFINITION.`
It must be specified with the same method name and in the same
visibility section as in the superclass. Specifying or changing the
signature is not possible.
- If you want to access the original method in the superclass within
the method implementation of the subclass, use the [pseudo
reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpseudo_reference_glosry.htm "Glossary Entry")
`super->...`.
> **💡 Note**<br>
> If the instance constructor is implemented in a subclass, the instance constructor of the superclass must be called explicitly using `super->constructor`, even if the latter is not explicitly declared. An exception to this: Direct subclasses of the root node object.
<p align="right">(<a href="#top">back to top</a>)</p>
## Notes on Polymorphism and Casting
The object orientation concept
[polymorphism](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpolymorphism_glosry.htm "Glossary Entry")
means accessing different methods in different objects and with
different behavior via the same interface, i. e. you can use one and the
same reference variable to access various objects, for example,
references to a superclass can point to objects of a subclass.
Note the concept of static and dynamic type in this context:
- Object reference variables (and also interface reference variables
as outlined further down) have both a
[static](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_type_glosry.htm "Glossary Entry")
and a [dynamic
type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendynamic_type_glosry.htm "Glossary Entry").
- When declaring an object reference variable, e. g. `DATA oref TYPE
REF TO cl`, you determine the static type, i. e.
`cl` is used to declare the reference variable that is
statically defined in your program. The dynamic type is determined
at runtime of the program and is the class of an object. Especially
in the context of assigning object or interface references (and also
[data
references](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_reference_glosry.htm "Glossary Entry")),
this differentiation enters the picture.
- The following basic rule applies: The assignment of an object or
interface reference variable to another one is possible if the
static type of the target reference variable is more general than or
the same as the dynamic type of the source reference variable.
- If it can be statically checked that an assignment is possible
although the types are different, the assignment is done using the
[assignment
operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_operator_glosry.htm "Glossary Entry")
`=` that triggers an
[upcast](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenup_cast_glosry.htm "Glossary Entry")
automatically.
- Otherwise, it is a
[downcast](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendown_cast_glosry.htm "Glossary Entry").
Here, the assignability is not checked until runtime. The downcast
must be triggered explicitly using [casting
operators](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencasting_operator_glosry.htm "Glossary Entry"),
either with the [constructor
operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_operator_glosry.htm "Glossary Entry")
[`CAST`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_cast.htm)
or the older
[`?=`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmove_cast.htm),
for the assignment of object or interface reference variables.
- See more information in the topic [Assignment Rules for Reference
Variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconversion_references.htm).
> **✔️ Hints**<br>
> - If the static type is a class, the dynamic type must be the same class or one of its subclasses.
> - If the static type is an interface, the dynamic type must implement the interface.
As an example, assume there is an inheritance tree with `lcl_super` as the superclass and `lcl_sub` as a direct subclass. `lcl_sub2` is a direct subclass of `lcl_sub`.
In the following code snippet, the rule is met since the superclass is either the same as or more generic than the subclass (the subclass has, for example, redefined methods and is, thus, more specific). Hence, the assignment of an object reference variable pointing to the subclass to a variable pointing to a superclass works. An upcast is triggered. After this casting, the type of `oref_super` has changed and the methods of `lcl_sub` can be accessed via `oref_super`.
``` abap
oref_super = NEW lcl_super( ).
oref_sub = NEW lcl_sub( ).
"Upcast
oref_super = oref_sub.
"The casting might be done when creating the object.
DATA super_ref TYPE REF TO lcl_super.
super_ref = NEW lcl_sub( ).
```
Such upcasts frequently occur if you want to access objects via an
object reference variable pointing to the superclass. However, there
might also be situations when you want to do the assignment the other
way round, i. e. going from specific to more generic. In this case, a
more generic reference variable is assigned to a specific variable which
can be depicted as moving downwards in the inheritance tree concerning
the assignment. As mentioned above, a downcast must be triggered
manually. Just an assignment like `oref_sub = oref_super.`
does not work. A syntax error occurs saying the right-hand variable's
type cannot be converted to the left-hand variable's type.
If you indeed want to carry out this casting, you must use
`CAST` or `?=` to overcome this syntax error (but just
the syntax error!). Note: You might also use these two
operators for the upcasts. That means, `oref_super =
oref_sub.` has the same effect as `oref_super = CAST #(
oref_sub ).`. This syntax is usually not necessary.
At runtime, the assignment is checked and if the conversion does not
work, you face a (catchable) runtime error. Even more so, the assignment
`oref_sub ?= oref_super.` does not throw a syntax error but it
does not work in this example either because it violates the rule
mentioned above (`oref_sub` is more specific than
`oref_super`). To check whether such an assignment is possible
on specific classes, you can use the predicate expression [`IS INSTANCE
OF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_instance_of.htm)
or the case distinction [`CASE TYPE
OF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcase_type.htm).
Carrying out an upcast before the downcast ensures that the left-hand
variable's type is compatible to the right-hand variable's type.
``` abap
oref_super = NEW lcl_super( ).
oref_sub = NEW lcl_sub( ).
oref_sub2 = NEW lcl_sub2( ).
"Downcast resulting in an error; error is caught
TRY.
  oref_sub = CAST #( oref_super ).
  CATCH CX_SY_MOVE_CAST_ERROR INTO DATA(e).
    ...
ENDTRY.
"Working downcast with a prior upcast
oref_super = oref_sub2.
"Due to the prior upcast, the following check is actually not necessary.
IF oref_super IS INSTANCE OF lcl_sub.
  oref_sub = CAST #( oref_super ).
  ...
ENDIF.
```
<p align="right">(<a href="#top">back to top</a>)</p>
## Working with Interfaces
Interfaces ...
- represent a template for the components in the public visibility
section of classes and thus enhance the components of classes by
adding components of interfaces.
- represent a means to deal with multiple inheritance in ABAP Object
Orientation.
- serve the concept of
[polymorphism](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpolymorphism_glosry.htm "Glossary Entry").
Any number of classes can implement the same interface.
- are beneficial if you want to share and reuse common components
across classes especially if those classes are not in an inheritance
relationship.
- are possible as both
[local](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlocal_interface_glosry.htm "Glossary Entry")
and [global
interfaces](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_interface_glosry.htm "Glossary Entry").
- are different from classes in the following ways:
- They only consist of a part declaring the components without an
implementation part. The classes using the interfaces are
responsible for the implementation.
- They do not include visibility sections. All interface
components are public.
- No instances can be created from interfaces.
- Declarations as mentioned for classes, e. g. `DATA`,
`CLASS-DATA`, `METHODS`,
`CLASS-METHODS`, are possible. Constructors are not
possible.
<p align="right">(<a href="#top">back to top</a>)</p>
**Defining Interfaces**
> **💡 Note**<br>
> The addition `DEFINITION` is not relevant here since there is no implementation part.
``` abap
INTERFACE intf.
"The addition PUBLIC is for global interfaces:
"INTERFACE intf_g PUBLIC.
    DATA ...
CLASS-DATA ...
METHODS ...
CLASS-METHODS ...
ENDINTERFACE.
```
<p align="right">(<a href="#top">back to top</a>)</p>
**Using Interfaces in Classes**
- A class can implement multiple interfaces.
- As a prerequisite, the interfaces must be specified in the
declaration part of a class using the statement
[`INTERFACES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces.htm).
- Since all interface components are public, you must include this
statement and the interfaces in the public section of a class.
- In doing so, the interface components become part of the class
itself. Methods that are specified in interfaces must be implemented
in the class unless the methods are marked as optional in the
interface using the additions [`DEFAULT
IGNORE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm)
or [`DEFAULT FAIL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm).
Furthermore, you can specify the addition [`ABSTRACT
METHODS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm)
for the `INTERFACES` statement in the declaration part of
classes followed by method names. In this case, the class need not
implement the methods of the interface. The implementation is then
relevant for a subclass inheriting from a superclass that includes
such an interface declaration. Find more information
[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm).
- You can specify alias names for the interface components using the
statement [`ALIASES ... FOR
...`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapaliases.htm).
The components can then be addressed using the alias name everywhere
(since the alias is public).
Syntax for using interfaces in classes:
``` abap
CLASS class DEFINITION.
  PUBLIC SECTION.
    INTERFACES intf1.
    INTERFACES intf2 ABSTRACT METHODS meth1. "No implementation required for meth1
    INTERFACES intf3 ALL METHODS ABSTRACT. "All methods abstract
    ALIASES meth_alias FOR intf1~some_method.
ENDCLASS.
CLASS class IMPLEMENTATION.
  METHOD intf1~some_meth. "Method implementation using the original name
   ...
  ENDMETHOD.
"Just for demo purposes: Method implementation using the alias name  
"METHOD meth_alias.  
  " ...
  "ENDMETHOD.
  ...
ENDCLASS.
```
<p align="right">(<a href="#top">back to top</a>)</p>
**Accessing Interface Components**
- Interface components can be addressed using the [interface component
selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninterface_comp_selector_glosry.htm "Glossary Entry"):
`... intf~comp ...`.
- Note: Due to the unique interface name and the use of
the name as prefix (e. g. `intf~`) that is followed by
a component name, there is no problem regarding the component
naming within a class, i. e. the class can have components with
the same name, and other interfaces can have components with the
same name, too.
- You can then access them either using class references or interface
references:
- Class references: `... class_ref->intf~comp ...`
- Interface references: `... i_ref->comp ...`. In this
case, the [object component
selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_component_select_glosry.htm "Glossary Entry")
is used to access the components without the interface name.
Before making use of interface references, an [interface reference
variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninterface_ref_variable_glosry.htm "Glossary Entry")
must be created: `DATA i_ref TYPE REF TO intf.` Interfaces
cannot be instantiated, i. e. an object cannot be created, however,
interface references can point to the objects of any class that includes
the interface so that interface components (and only them) can be
accessed via the variable. Accessing an object via an interface
reference variable is basically the same as accessing a subclass object
via a superclass reference variable.
<p align="right">(<a href="#top">back to top</a>)</p>
**Assigning Interface Reference Variables**
As mentioned above, interface references can point to the objects of any
class that includes the interface. This is true when object references
are assigned to interface references. Here, as touched on before, the
concept of
[upcasting](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenup_cast_glosry.htm "Glossary Entry")
enters the picture.
``` abap
DATA i_ref TYPE REF TO intf.
DATA cl_ref TYPE REF TO class.
cl_ref = NEW #( ).
"Upcast
i_ref = cl_ref.
"Method call using the interface reference variable
i_ref->some_method( ... ).
```
The other way round, i. e. the assignment of an interface reference to
an object reference, is also possible
([downcast](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendown_cast_glosry.htm "Glossary Entry")
or narrowing cast). However, as mentioned before, this assignment can be
problematic since a successful assignment is dependent on whether the
object the interface reference points to is actually an object of the
implementing class. If this is not the case, a runtime error occurs. You
can carry out a downcast using the casting operator
[`CAST`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_cast.htm)
or the operator
[`?=`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmove_cast.htm).
The example shows the use of an [`IS INSTANCE
OF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_instance_of.htm)
expression to prevent a runtime error as also shown before.
``` abap
DATA i_ref TYPE REF TO intf.
DATA cl_ref TYPE REF TO class.
cl_ref = NEW #( ).
IF i_ref IS INSTANCE OF class.
  cl_ref = CAST #( i_ref ).
...
ENDIF.
```
> **✔️ Hints**<br>
> Interfaces versus abstract classes<br>
> Coming back to
[abstract](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabstract_glosry.htm "Glossary Entry")
classes in the context of interfaces. Like interfaces, abstract classes
cannot be instantiated - only their subclasses. The following list
includes differences between abstract classes and interfaces that should
be considered when creating them:
>- Abstract classes can have components (including abstract and
non-abstract methods) in other visibility sections than only public.
>- Multiple inheritance is impossible with abstract classes since there
can be only one abstract class as superclass.
>- Non-abstract methods in abstract classes can be implemented whereas
interfaces do not allow any method implementations.
<p align="right">(<a href="#top">back to top</a>)</p>
## Further Concepts
### Factory Methods
A factory method is relevant if you want to restrict and control the
instantiation of a class by external users of this class. Still, the
users should be able to work with objects of the class. This is true for
cases when, for example, there must be only a single object of a class
(a singleton) or certain checks must be carried out before a class can
be instantiated so as to guarantee a consistent creation of all objects.
A (static) factory method implemented in such a class does the trick: It
creates an object of the class and returns a reference to the object.
Example for a class and factory method:
``` abap
"Addition CREATE PRIVATE
CLASS class DEFINITION CREATE PRIVATE.
  PUBLIC SECTION.
  CLASS-METHODS factory_method
         IMPORTING ...
         RETRUNING VALUE(obj) TYPE REF TO class. "Returns an object
ENDCLASS.
...
"Calling a factory method.
DATA obj_factory TYPE REF TO class.
obj_factory = class=>factory_method( ... ).
```
<p align="right">(<a href="#top">back to top</a>)</p>
### Friendship
Classes can grant friendship to other classes and interfaces to enable
the access to protected and private components. However, the friendship
is not reciprocal. If class `a` grants friendship to class `b`, class `b` must
also explicitly grant friendship to class `a` if the component should be
made accessible also the other way round.
Friends of a class can create instances of the class without any
restrictions. They are not automatically made friends of the subclasses
of the class.
Friendship prevents that the components are made available to all users.
A typical use case for friendship between classes is [unit
tests](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunit_test_glosry.htm "Glossary Entry"),
i. e. friendship is granted to test classes so that they can access and
test private components, too.
You specify the befriended class in the definition part:
``` abap
CLASS class DEFINITION FRIENDS other_class.
...
```
<p align="right">(<a href="#top">back to top</a>)</p>
### Events
[Events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenevent_glosry.htm "Glossary Entry")
are components of classes that can be triggered by methods. If an event
is raised (by a [`RAISE EVENT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapraise_event.htm)
statement), specific [event handler
methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenevent_handler_glosry.htm "Glossary Entry")
are called to react on the event. The following points are relevant for
raising events:
- Defining events
- Events must be defined in a visibility section of the
declaration part of a class or in an interface, e. g. as
instance (using an
[`EVENTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapevents.htm)
statement) or static events
([`CLASS-EVENTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass-events.htm)).
- Similar to methods, static events can be triggered by instance
and static methods, instance events can only be triggered by
instance methods.
- Events allow exporting parameters to be defined. They must be
passed by value. Each instance event also includes the implicit
output parameter `sender` representing an object
reference variable for the instance for which the event is
defined.
- Defining and implementing [event handler
methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenevent_handler_glosry.htm "Glossary Entry").
These methods are defined with a special syntax:
``` abap
CLASS-METHODS handler_meth FOR EVENT evt OF class
...
```
- Registering event handler methods
- Event handler methods must be registered using a [`SET
HANDLER`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapset_handler.htm)
statement at runtime so that they can handle a raised event at
all and react accordingly.
- You can register instance events for a specific instance or for
all instances of a class. Static events are registered to the
whole class without any addition to the `SET HANDLER`
statement.
```abap
SET HANDLER handler_meth FOR ref. "Specific instance
SET HANDLER handler_meth FOR ALL INSTANCES. "All instances
SET HANDLER handler_meth. "For static events
```
<p align="right">(<a href="#top">back to top</a>)</p>
## Executable Example
[zcl_demo_abap_objects](./src/zcl_demo_abap_objects.clas.abap)
Note the steps outlined [here](README.md#🎬-getting-started-with-the-examples) about how to import and run the code.