Ansicht
Dokumentation

ABAPSHEETS_ABAP_OO - SHEETS ABAP OO

ABAPSHEETS_ABAP_OO - SHEETS ABAP OO

Addresses (Business Address Services)   BAL_S_LOG - Application Log: Log header data  
This documentation is copyright by SAP AG.
SAP E-Book

ABAP Object Orientation

This cheat sheet provides high-level information on working with syntax and concepts related to ABAP object orientation. It gathers some basics supported by code examples in one place for your reference. These examples are not considered being a role model for object-oriented design. They are put together to focus 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.

Classes and Objects

Dealing with ABAP Objects means you will inevitably face classes and objects.

Objects ...

  • are often described as instances of classes, hence, the terms object and instance are synonymous.
  • attributes of the objects (the data declarations)

  • methods that typically operate on that data

  • events (see details on events further down)

Classes ...

  • are descriptions of objects, i. e. they provide the template how all instances of a class look like. All instances are created based on this template (the creation is called instantiation).
  • 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 calculation of the braking distance. 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 calculated braking distance of 15 meters, 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.

Creating Classes

You can either create local or global classes.

Local classes...

  • can be defined within an ABAP program.
  • can only be used in the program in which the class is defined.

Global classes...

  • can be used by all ABAP programs since they are globally visible.

  • Regarding the names of global and local classes and usage of classes in ABAP programs, 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, 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.

The basic structure of classes consist of a declaration and an implementation part.

Create a local class with the following code:

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.

Create a global class with the following code. The code snippet shows a basic skeleton of a global class. There are further additions possible, for example, in the context of abstract classes. Refer to the class section in the ABAP keyword documentation.

CLASS global_class DEFINITION
  PUBLIC   "Makes the class a global class.
  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.

Visibility of Components

In the class definition part, you must specify visibility sections 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:

  • PUBLIC.: Components can be accessed from within the class and from outside.
  • PRIVATE.: Components can only be accessed from within the class in which they are declared.

Create the visibility sections with the following code. At least one section must be specified.

CLASS local_class DEFINITION.
    PUBLIC.
      "Here go the components.
    PROTECTED.
      "Here go the components.
    PRIVATE.
      "Here go the components.
ENDCLASS.
...

  • As mentioned above, public components must be specified with care since they may not be changed once the class has been released.
  • The READ-ONLY addition can be used as a means of making components publicly accessible but securing them against undesired changing from outside.

Defining Components

All components - attributes, methods, events - are declared in the DEFINITION part of the class. There, they must be assigned to a visibility section.

There are two kinds of components:

  • Instance components: Components that exist separately for each object and can only be accessed in objects of a class.
  • Static components: Components that are not specific for objects but shared by all objects. They exist only once per class and can be accessed using the name of the class.

Attributes

  • The attributes of a class mean the actual data fields.
  • Static attributes: Since they are independent of the objects and relate to all objects, changing an instance attribute means the change is visible in all objects. You declare them using CLASS-DATA statements in a visibility section. As shown further down, static attributes can be accessed without a prior creation of an object.
  • Instance attributes: Determine the object-specific state. The data is only valid in the context of an object. You declare them using DATA statements in a visibility section. As shown further down, instance attributes can only be accessed via an object reference variable.

  • Static methods can only access static attributes. Instance methods can access both static and instance attributes.
  • You can declare static attributes that should not be changed using CONSTANTS statements. You specify the values for the constants when you declare them.

Declare attributes in visibility sections. In the snippet below, all attributes are declared in the PUBLIC. section.

CLASS local_class DEFINITION.
    PUBLIC.
      DATA: inst_number TYPE i,                "Instance attributes
            inst_string TYPE string.
      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.

Methods

  • Determine the behavior of the class.
  • Can access all of the attributes of a class and, if not defined otherwise, change their content.
  • Static methods: 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: Can access all of the attributes of a class and trigger all events. You declare them using CLASS statements in a visibility section.

Parameter interface

In the simplest form, methods can have no parameter at all. Apart from that, methods can be defined with the following parameters:

  • 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, 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.
  • 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.

  • There are plenty of options for further detailing out the parameter definitions. For example, you can specify if the data should be passed by value or reference (which is beneficial in terms of performance), or if parameters are optional. Find more information in the topic METHODS, parameters. The executable example also includes the use of generic ABAP types (... TYPE DATA ... and ... TYPE ANY TABLE ...) in method signatures.

Constructors

  • Constructors 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.
  • The definition and use is optional but if used, they must always be defined in the public visibility section and then, consequently, be implemented.
  • Static constructor: Automatically called when you access static components of a class for first time. Like other static methods, this constructor is defined using the predefined name class_constructor as part of a CLASS-METHODS statement. Static constructors cannot have any parameters.
  • Instance constructor: Automatically called when you create an object. Like other instance methods, this constructor is defined using the predefined name constructor as part of a METHODS statement. Instance constructors can only have IMPORTING parameters and exceptions. In case of exceptions, make sure to use a TRY ... ENDTRY. block in the implementation since otherwise the instance is not created if uncaught errors occur.

Constructors are always present even if you do not define them explicitly. They are called automatically and implicitly. And if they are not defined and used, they simply have no effect.

Example for method definitions. The following snippet shows multiple method definitions in the public section.

CLASS local_class DEFINITION.
    PUBLIC.
      METHODS: inst_meth1 IMPORTING imp TYPE i   "instance methods
                          EXPORTING exp TYPE i,
               inst_meth2 IMPORTING s1 TYPE string
               inst_meth2 IMPORTING imp_str       TYPE string
                          RETURNING VALUE(result) TYPE string,
               inst_meth3 IMPORTING imp_str       TYPE string
                          EXPORTING exp_i         TYPE i
                          CHANGING  ch_tab        TYPE string_table
                          RETURNING VALUE(result) TYPE string
                          RAISING   cx_sy_zerodivide,
            constructor IMPORTING imp_con TYPE i.  "instance constructor

      CLASS-METHODS: stat_meth1 IMPORTING imp_i TYPE i   "Static methods
                                EXPORTING exp_i TYPE i,
                     class_constructor.  "static constructor
...
ENDCLASS.

CLASS local_class IMPLEMENTATION.
   METHOD inst_meth1.
      ...           "Here goes the method implementation.
   ENDMETHOD.
...                 "Note that all defined methods must be implemented.
ENDCLASS.

Working with Objects and Components

Declaring reference variables: To create an object, a reference variable must be declared. This variable is also necessary for accessing objects, i. e. objects are not directly accessed but only via references that point to those objects. This reference is stored in the reference variables.

DATA: ref1 TYPE REF TO local_class,
      ref2 TYPE REF TO local_class,
      ref3 LIKE ref1.

Creating objects: You create an object in the memory of an application by using the instance operator NEW. In doing so, a new instance of a class is created and the "address" of the instance is put into the reference variable. The # sign means that you use the type (TYPE REF TO ...) of the reference variable. You can also omit the explicit declaration of a reference variable by declaring a new reference variable inline. In this case, the name of the class must be placed after NEW. As an alternative to the NEW operator, you can also use the older CREATE OBJECT statements.

ref1 = NEW #( ). "Type derived from already declared ref1

DATA(ref2) = NEW local_class( ). "Inline declaration

CREATE OBJECT ref3. "Type derived from already declared ref3

Assigning or copying reference variables: To assign or copy reference variables, use the assignment operator =. In the example below, both reference variables have the same type. You might also stumble upon obsolete MOVE ... TO ... statements. Do not use them.

DATA: ref1 TYPE REF TO local_class,
      ref2 TYPE REF TO local_class.

ref1 = NEW #( ).
ref2 = ref1.
MOVE ref1 TO ref2. "Obsolete syntax. Do not use.

Overwriting reference variables: An object reference is overwritten when a new object is created with a reference variable already pointing to an instance.

ref = NEW #( ).
ref = 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 retains their values.

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 ) ). "Adds the reference to itab.
    ENDDO.

Clearing object references: Use CLEAR statements to explicitly clear a reference variable.

CLEAR ref.

Since objects use up space in the memory, they should be cleared if they are no longer needed. The garbage collector 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 -> via a reference variable. Visible static attributes are accessed using the class component selector => via the class name. You can also declare variables by referring to those attributes.

"Accessing instance attribute via ref variable
... ref->some_attribute ...

"Accessing static attribute via class name
... local_class=>static_attribute ...
... static_attribute ... "Without the class name only within the class

"Variable declaration
DATA var1 TYPE local_class=>some_type.
DATA var2 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 statements which are not used here. When methods are called, the parameters must be specified within the parentheses. See the executable example for demonstrations of various method definitions and method calls.

Instance and static method calls:

"Calling instance methods via reference variable.
ref->inst_meth( ... ).

"Calling static methods via/without the class name
class_name=>stat_meth( ... ).
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, you export values to the method having
"importing parameters defined. Hence, the ABAP word EXPORTING is
"relevant. The three following method calls are the same.
class_name=>meth( EXPORTING a = b ). "Explicit use of EXPORTING.

"Only importing parameters in the signature: EXPORTING not needed.
class_name=>meth( a = b ).

"Only a single value must be passed: param. name + 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.
DATA(result) = class_name=>meth( i = j k = l ) "i/k: importing params.

"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.
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 includes 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 reference variable me which is always available and points to the respective object itself. You could use it to refer to components of the instance of a particular class but it's not needed:

... 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.

METHOD me_ref.
DATA str TYPE string VALUE `Local string`.
DATA(local_string) = str.

"Assuming there is a variable str declared in the class definition part.
DATA(other_string) = me->str.
ENDMETHOD.

Touching on Inheritance

  • Concept: Derive a new class (subclass) from an existing one (superclass) to share common code between classes. In doing so, you create hierarchies of classes (a kind of inheritance tree) while a superclass includes characteristics that are shared by all subclasses to provide a better structure for your code.
  • Subclasses ...
  • inherit from superclasses and can both access their instance attributes and redefine their instance methods (i. e. replace the implementations of inherited methods).

  • can add new components.

  • 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. 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 the respective class 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. The addition ABSTRACT is meant for 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. See more details on abstract classes in the context of interfaces further down.

Regarding the redefinition of methods:

  • The method from the superclass that is redefined must be specified in the definition 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 super->....

Notes on Polymorphism and Casting

The object orientation concept polymorphism 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 and a dynamic type. 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 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 as shown here), this differentiation comes into 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 = that triggers an upcast automatically. Otherwise, it is a downcast. Here, the assignability is not checked until runtime. The downcast must be triggered explicitly using casting operators, either with the constructor operator CAST or the older ?=, for the assignment of object or interface reference variables. See more information in the topic Assignment Rules for Reference Variables.

Notes

  • 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 subclass. lcl_sub2 is a subclass of lcl_sub.

In the following code snippet, the rule applies that 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. See it in action in the executable example.

oref_super = NEW lcl_super( ).
oref_sub = NEW lcl_sub( ).

oref_super = oref_sub. "Upcast

"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!). 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 or the case distinction CASE TYPE OF. Carrying out an upcast before the downcast ensures that the left-hand variable's type is compatible to the right-hand variable's type.

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.

IF oref_super IS INSTANCE OF lcl_sub. "Due to the prior upcast, this check is actually not necessary.
  oref_sub = CAST #( oref_super ).
  ...
ENDIF.

Working with Interfaces

Interfaces ...

  • represent a means to deal with multiple inheritance in ABAP Object Orientation.
  • serve the concept of polymorphism. 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 similar to (abstract) classes, i. e. they can have the same set of components like classes. Both local and global interfaces are possible.
  • 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.

Defining interfaces

The addition DEFINITION is not relevant here since there is no implementation part.

INTERFACE intf.
"INTERFACE intf_g PUBLIC. "The addition PUBLIC is for global interfaces
DATA ... CLASS-DATA ... METHODS ... CLASS-METHODS ...
...
ENDINTERFACE.

Using interfaces in classes

  • A class can implement multiple interfaces.
  • As a prerequisite, the interfaces must be specified in the definition part of a class using the statement INTERFACES.
  • 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 using the additions DEFAULT IGNORE or DEFAULT FAIL.
  • You can specify alias names for the interface components using the statement ALIASES ... FOR .... The components can then be addressed using the alias name everywhere (since the alias is public).

Syntax for using interfaces in classes:

CLASS class DEFINITION.
PUBLIC SECTION.
INTERFACES: intf1, intf2 ...
ALIASES meth_alias FOR intf2~method.
ENDCLASS.

CLASS class IMPLEMENTATION.
METHOD intf1~some_meth. ... ENDMETHOD.
METHOD meth_alias. ... ENDMETHOD.
...
ENDCLASS.

Accessing interface components

  • 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 is used to access the components without the interface name.

Before making use of interface references, an interface reference variable 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.

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 comes into the picture.

DATA i_ref TYPE REF TO intf.
DATA cl_ref TYPE REF TO class.

cl_ref = NEW #( ).
i_ref = cl_ref. "Upcast
i_ref->some_method( ... ).

The other way round, i. e. the assignment of an interface reference to an object reference, is also possible ( downcast 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 or the operator ?=. The example shows the use of an IS INSTANCE OF expression to prevent a runtime error as also shown before.

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.

Interfaces versus abstract classes

Coming back to abstract 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.
  • Adding a new method to an interface means that users of that interface are forced to implement the method, too, whereas new non-abstract methods declared in abstract classes need not be implemented in inherited classes.
  • Non-abstract methods in abstract classes can be implemented whereas interfaces do not allow any method implementations.

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:

CLASS class DEFINITION CREATE PRIVATE. "Addition 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( ... ).

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. Friendship prevents that the components are made available to all users. A typical use case for friendship between classes is unit tests, i. e. friendship is granted to test classes so that they can access and test private components, too. Friendship affects inheritance, i. e. classes that inherit from friends also become friends.

You specify the befriended class in the definition part:

CLASS class DEFINITION FRIENDS other_class. ...

Events

Events are components of classes that can be triggered by methods. If an event is raised (by a RAISE EVENT statement), specific event handler methods 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 definition part of a class or in an interface, e. g. as instance (using an EVENTS statement) or static events (CLASS-EVENTS).

  • 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.

  • These methods are defined with a special syntax:

$[CLASS-$]METHODS handler_meth FOR EVENT evt OF class ...
  • Registering event handler methods
  • Event handler methods must be registered using a SET HANDLER 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.

SET HANDLER handler_meth FOR ref. "Specific instance
SET HANDLER handler_meth FOR ALL INSTANCES. "All instances
SET HANDLER handler_meth. "For static events

Demonstration Program

The example ABAP Object Orientation demonstrates the syntactical options and concepts mentioned above and beyond in one program.






BAL Application Log Documentation   General Data in Customer Master  
This documentation is copyright by SAP AG.

Length: 54708 Date: 20240509 Time: 170115     sap01-206 ( 759 ms )