ABAP OO - Interface (DEFAULT IGNORE)
This article is about the development of an interface with the addition DEFAULT and the consequences for implementation and use.
Table of contents
When writing the article for exits in application jobs, we came across a construct that we had not seen before. Today we want to share our impressions and work with such interfaces with you and go through the details of the implementation.
Introduction
What exactly is this article about? Interfaces are usually defined in such a way that the user must implement all methods in their code, otherwise the class cannot be activated. This may mean that you create 20 methods, but you actually only want to implement one method. For this purpose, the addition DEFAULT was introduced in the method definition, which we would like to discuss in this article.
Interface
To do this, we define a mixed interface where all types of methods are defined. We use a normal method for which we need an implementation later, two methods with DEFAULT IGNORE and one method with DEFAULT FAIL. The interface is defined as follows:
INTERFACE zif_bs_demo_intf_default
PUBLIC.
METHODS:
method_with_implementation
IMPORTING id_value TYPE string
RETURNING VALUE(rd_result) TYPE abap_bool,
method_with_default_bool DEFAULT IGNORE
IMPORTING id_value TYPE string
RETURNING VALUE(rd_result) TYPE abap_bool,
method_with_default_integer DEFAULT IGNORE
IMPORTING id_value TYPE string
RETURNING VALUE(rd_result) TYPE i,
method_with_fail DEFAULT FAIL
IMPORTING id_value TYPE string
RETURNING VALUE(rd_result) TYPE abap_bool.
ENDINTERFACE.
There are two extensions for the DEFAULT addition:
- IGNORE - If the method is not implemented, then the implementation behaves like an empty method implementation (initial parameters).
- FAIL - If the method is not implemented and is called, then an exception (CX_SY_DYN_CALL_ILLEGAL_METHOD) is thrown, but only when a call is made.
Implementation
In the next step we want to test the standard implementation of the interface and create an executable class and implement the interface. To do this, we specify the two interfaces in the wizard:
By default, the class is created with all methods, so the wizard automatically implements methods that are marked as DEFAULT:
CLASS zcl_bs_demo_intf_default DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
INTERFACES zif_bs_demo_intf_default.
ENDCLASS.
CLASS zcl_bs_demo_intf_default IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
ENDMETHOD.
METHOD zif_bs_demo_intf_default~method_with_default_bool.
ENDMETHOD.
METHOD zif_bs_demo_intf_default~method_with_default_integer.
ENDMETHOD.
METHOD zif_bs_demo_intf_default~method_with_fail.
ENDMETHOD.
METHOD zif_bs_demo_intf_default~method_with_implementation.
ENDMETHOD.
ENDCLASS.
To test, we now delete all methods from our interface and try to implement them again using the "Quick Fix" (CTRL + 1). We notice that this time only our mandatory method is created:
The quick fix does not work for the other methods and the other methods must be implemented manually.
Testcode
Now let's implement our test code to test the class. To do this, we create the following coding in the Main method to validate the functionality of the individual methods without implementation.
DATA lo_test TYPE REF TO zif_bs_demo_intf_default.
lo_test = NEW zcl_bs_demo_intf_default( ).
out->write( |Normal implementation: { lo_test->method_with_implementation( `Normal` ) }| ).
out->write( |Default with Bool: { lo_test->method_with_default_bool( `Default` ) }| ).
out->write( |Default with Integer: { lo_test->method_with_default_integer( `Default` ) }| ).
TRY.
out->write( |Default to Fail: { lo_test->method_with_fail( `Fail` ) }| ).
CATCH cx_sy_dyn_call_illegal_method.
out->write( `Method failed` ).
ENDTRY.
We implement the mandatory method accordingly and return ABAP_TRUE to get a result. The entire class at this point looks like this:
CLASS zcl_bs_demo_intf_default DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
INTERFACES zif_bs_demo_intf_default.
ENDCLASS.
CLASS zcl_bs_demo_intf_default IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA lo_test TYPE REF TO zif_bs_demo_intf_default.
lo_test = NEW zcl_bs_demo_intf_default( ).
out->write( |Normal implementation: { lo_test->method_with_implementation( `Normal` ) }| ).
out->write( |Default with Bool: { lo_test->method_with_default_bool( `Default` ) }| ).
out->write( |Default with Integer: { lo_test->method_with_default_integer( `Default` ) }| ).
TRY.
out->write( |Default to Fail: { lo_test->method_with_fail( `Fail` ) }| ).
CATCH cx_sy_dyn_call_illegal_method.
out->write( `Method failed` ).
ENDTRY.
ENDMETHOD.
METHOD zif_bs_demo_intf_default~method_with_implementation.
rd_result = abap_true.
ENDMETHOD.
ENDCLASS.
Execution
Let's run the class in its current state and look at the result. Since it is an executable class, we can start it with F9 and have the result displayed in the console.
As expected the first three methods were executed and the last method ran into errors, there is no output here as an exception was thrown. The two methods with DEFAULT IGNORE provided initial return values and were run successfully.
FAIL
Finally, we implement the method with DEFAULT FAIL for testing, create the method and return ABAP_TRUE.
METHOD zif_bs_demo_intf_default~method_with_fail.
rd_result = abap_true.
ENDMETHOD.
The method should now run cleanly and no longer throw an exception. After executing the class, we get the following result, just as we expected:
Complete example
Finally, the complete implementation of the class; you can find the interface at the top of the article.
CLASS zcl_bs_demo_intf_default DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
INTERFACES zif_bs_demo_intf_default.
ENDCLASS.
CLASS zcl_bs_demo_intf_default IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA lo_test TYPE REF TO zif_bs_demo_intf_default.
lo_test = NEW zcl_bs_demo_intf_default( ).
out->write( |Normal implementation: { lo_test->method_with_implementation( `Normal` ) }| ).
out->write( |Default with Bool: { lo_test->method_with_default_bool( `Default` ) }| ).
out->write( |Default with Integer: { lo_test->method_with_default_integer( `Default` ) }| ).
TRY.
out->write( |Default to Fail: { lo_test->method_with_fail( `Fail` ) }| ).
CATCH cx_sy_dyn_call_illegal_method.
out->write( `Method failed` ).
ENDTRY.
ENDMETHOD.
METHOD zif_bs_demo_intf_default~method_with_implementation.
rd_result = abap_true.
ENDMETHOD.
METHOD zif_bs_demo_intf_default~method_with_fail.
rd_result = abap_true.
ENDMETHOD.
ENDCLASS.
Conclusion
The use was new for us, maybe even for you? The article is intended to help you understand what is possible with it. According to the documentation, it will primarily be used in the area of BADIs, but released objects from SAP will also be equipped with it.
Source:
SAP-Help - Methods DEFAULT