SAP ABAP OBJ PROGR MODEL - Guide
Get Example source ABAP code based on a different SAP table
GUIDELINE 3.1
ABAP Objects as a Programming Model
ABAP_BACKGROUND
ABAP is a hybrid programming language that supports both a procedural and an object-oriented programming model. The procedural programming model is based on the modularization of programs in classical processing blocks (event blocks, dialog modules, function modules and subroutines). In ABAP Objects, the class conceptually supersedes the classical program, and modularization is implemented using methods. From a technical point of view, classes are still declared and implemented in programs.
Both models possess interoperability, meaning that classes can be accessed in classical processing blocks and classical programs and procedures can be called within methods. The hybrid nature of the language is mainly due to the downward compatibility. This is because ABAP has procedural roots, and the introduction of the object-oriented programming model was intended to make sure entire programs and reusable procedures (primarily function modules) could still be used.
ABAP_RULE
Use ABAP objects wherever possible for new and further developments. Classical processing blocks should only be created in exceptional cases.
ABAP_DETAILS
The need to achieve
ABAP Objects enables an advanced type of data encapsulation to be used. In classical procedural programming, the state of an application is determined by the content of the global variables of a program. In object-oriented programming, the state is encapsulated in classes or objects as instances of classes. The distribution of data across the different visibility sections of a class public, protected and private allows a clear differentiation between externally and internally usable data. Even without in-depth object-oriented modeling, application programs benefit from these properties in terms of stability and maintainability.
ABAP Objects enables multiple instantiation of a class, by using explicit object creation with the
ABAP Objects enables the reuse of classes through inheritance, where classes with special behaviors are derived from more general classes. Only the differences must be implemented again. In the procedural model, only existing functions can be used as they are, or new functions must be created.
In ABAP Objects, objects can be addressed using standalone interfaces. This means that developers do not need to concern themselves with the implementation details of the class behind the interface. The provider of an interface can change the underlying implementations, without having to modify the programs that the interface uses. The procedural model does not have this concept of standalone interfaces.
ABAP Objects makes it easier to implement event-driven program flows. A
ABAP Objects contains a small number of closely defined, mutually orthogonal, fundamental concepts, which makes it more reliable and less error-prone than classical ABAP. Classical procedural ABAP is dominated by implicit behaviors, where programs are controlled by implicit events of the runtime environment and by global data. The concepts of ABAP Objects, however, are explicitly shown in a program. ABAP Objects is easier to learn and use than classical procedural ABAP.
ABAP Objects uses cleansed syntax rules and semantics rules. Classical procedural ABAP is a language that has evolved over time, and contains several obsolete and overlapping concepts. The introduction of ABAP Objects meant that classes and methods provided a field for cleansed syntax and semantics rules, which was completely unaffected by downward compatibility requirements. This meant that most obsolete and error-prone language constructs were syntactically forbidden in ABAP Objects (within classes and methods). Also, any questionable and potentially incorrect data accesses are checked more closely and can also be forbidden. The syntax cleansing enforces the use of the ABAP language in classes, which can only be requested using the
ABAP Objects is often the only way of dealing with new ABAP technologies. For example, GUI controls, Web Dynpro ABAP,
Therefore the urgent recommendation to use ABAP Objects has both formal and content-related issues:
The section
Exception
The following properties are still missing in ABAP Objects. They are needed to replace classical processing blocks with methods:
In these cases, the following classical processing blocks can still be created in new programs:
Within this type of processing block, however, the execution should be delegated immediately to a suitable method This does not have to be a method of a global class, but it can be located in the associated main program within the scope of a local class. To ensure that the system implements the same stricter check in these processing blocks as in the methods, the obsolete statements check (
Bad example
The following source code contains a rudimentary implementation for handling different types of bank accounts in a function group and their use in a program. Only the withdrawal of an amount function is shown. The function modules of the function group work on external data that is loaded into a global internal table in the
WITH UNIQUE KEY id.
'fetch amount for all accounts into account_tab
...
...
FUNCTION withdraw.
*'-----------------------------------------------------
*' IMPORTING
*' REFERENCE(id) TYPE accounts-id
*' REFERENCE(kind) TYPE c DEFAULT 'C'
*' REFERENCE(amount) TYPE accounts-amount
*' EXCEPTIONS
*' negative_amount
*' unknown_account_type
*'------------------------------------------------------
CASE kind.
WHEN 'C'.
PERFORM withdraw_from_checking_account
USING id amount.
WHEN 'S'.
PERFORM withdraw_from_savings_account
USING id amount.
WHEN OTHERS.
RAISE unknown_account_type.
ENDCASE.
ENDFUNCTION.
USING l_id TYPE accounts-id
l_amount TYPE accounts-amount.
FIELD-SYMBOLS <(><<)>account> TYPE accounts.
ASSIGN account_tab[ KEY primary_key id = l_id ] TO <(><<)>account>.
<(><<)>account> = <(><<)>account> - l_amount.
IF <(><<)>account> <(><<)> 0.
'Handle debit balance
...
ENDIF.
ENDFORM.
USING l_id TYPE accounts-id
l_amount TYPE accounts-amount.
FIELD-SYMBOLS <(><<)>account> TYPE accounts.
ASSIGN account_tab[ KEY primary_key id = l_id ] TO <(><<)>account>.
IF <(><<)>account>-amount > l_amount.
<(><<)>account>-amount = <(><<)>account>-amount - l_amount.
ELSE.
RAISE negative_amount.
ENDIF.
ENDFORM.
...
EXPORTING
id = ...
kind = 'C'
amount = ...
EXCEPTIONS
unknown_account_type = 2
negative_amount = 4.
CASE sy-subrc.
WHEN 2.
...
WHEN 4.
...
ENDCASE.
...
CALL FUNCTION 'WITHDRAW'
EXPORTING
id = ...
kind = 'S'
amount = ...
EXCEPTIONS
unknown_account_type = 2
negative_amount = 4.
CASE sy-subrc.
WHEN 2.
...
WHEN 4.
...
ENDCASE.
Good example
The following source code contains a rudimentary implementation for handling different types of bank accounts in classes and their use in a class. Only the withdrawal of an amount function is shown.
The different types of accounts are implemented in subclasses of an abstract class for accounts. Each instance of an account is provided with the required data in its constructor. If required, the application class generates instances of accounts of the required type and uses their methods polymorphically by means of a superclass reference variable. Exception handling is carried out using class-based exceptions.
INHERITING FROM cx_static_check.
ENDCLASS.
PUBLIC SECTION.
METHODS: constructor IMPORTING id TYPE string,
withdraw IMPORTING amount TYPE i
RAISING cx_negative_amount.
PROTECTED SECTION.
DATA amount TYPE accounts-amount.
ENDCLASS.
METHOD constructor.
'fetch amount for one account into attribute amount
...
ENDMETHOD.
METHOD withdraw.
me->amount = me->amount - amount.
ENDMETHOD.
ENDCLASS.
INHERITING FROM cl_account.
PUBLIC SECTION.
METHODS withdraw REDEFINITION.
ENDCLASS.
METHOD withdraw.
super->withdraw( amount ).
IF me->amount <(><<)> 0.
'Handle debit balance
...
ENDIF.
ENDMETHOD.
ENDCLASS.
INHERITING FROM cl_account.
PUBLIC SECTION.
METHODS withdraw REDEFINITION.
ENDCLASS.
METHOD withdraw.
IF me->amount > amount.
super->withdraw( amount ).
ELSE.
RAISE EXCEPTION TYPE cx_negative_amount.
ENDIF.
ENDMETHOD.
ENDCLASS.
********************************************************
PUBLIC SECTION.
CLASS-METHODS main.
ENDCLASS.
METHOD main.
DATA: account1 TYPE REF TO cl_account,
account2 TYPE REF TO cl_account.
...
EXPORTING
id = ...
EXPORTING
id = ...
...
account1->withdraw( ... ).
account2->withdraw( ... ).
CATCH cx_negative_amount.
...
ENDTRY.
ENDMETHOD.
ENDCLASS.