ABAP Quick - Classes for an interface
Read and validate all implementing classes for an interface. We'll show you how to do it easily and use it dynamically.
Table of contents
If you are building an application that provides an interface, you might also want to know which classes are based on that interface. Or you would like to automatically include the classes for processing? Then you are in the right place! In today's article we want to summarize briefly how you can read the classes and work with them automatically.
Preparation
What we need for this scenario is first of all an interface that we can implement. In addition also 2 to 3 classes which take over the interface. For the test, some methods are also implemented and some not yet. We would like to show you how you can catch errors in case of a lack of implementation.
The interface in our example is called ZIF_TEST_SST and should symbolize an interface. The interface has two methods and a constant. The first step is to check if the class is relevant for processing. If so, the constant is returned. The second step is to execute the processing via the execute method.
Definition
As a class definition, we only need two methods for determining the classes and executing them. In addition the following coding:
CLASS lcl_prog DEFINITION.
PUBLIC SECTION.
TYPES:
" Klassennamen
tt_class TYPE STANDARD TABLE OF char30 WITH EMPTY KEY.
CLASS-METHODS:
get_class
IMPORTING
id_intf TYPE clike
RETURNING VALUE(rt_class) TYPE tt_class,
start_impl
IMPORTING
id_class TYPE clike.
PRIVATE SECTION.
ENDCLASS.
Read all classes
With the method get_class we read all classes where the interface is directly assigned. Then we delimit the corresponding includes that interest us, convert the name and check if the class really exists in the system. If everything is alright, we append the class into the return table.
METHOD get_class.
" CHeck for used interface
SELECT include FROM wbcrossgt
WHERE otype = 'TY'
AND name = @id_intf
AND direct = @abap_true
INTO TABLE @DATA(lt_class).
" Check the found classes
LOOP AT lt_class INTO DATA(ls_class) WHERE include 30 = 'CU'.
" Prepare name
DATA(ld_name) = ls_class-include(30).
TRANSLATE ld_name USING '= '.
" Validate name and type
SELECT SINGLE typename FROM ddtypes
INTO @DATA(ls_check)
WHERE typename = @ld_name
AND state = 'A'
AND typekind = 'CLAS'.
" Append to table
IF sy-subrc = 0.
APPEND ld_name TO rt_class.
ENDIF.
ENDLOOP.
ENDMETHOD.
Start implementation
In the second step, we define a method that executes the found classes one after the other and reacts in case of an error. You can then decide whether a method in the class has not yet been implemented or other critical errors have occurred during processing.
METHOD start_impl.
DATA:
lo_obj TYPE REF TO zif_test_sst.
TRY.
" Create instance
CREATE OBJECT lo_obj TYPE (id_class).
" Check, if relevant
IF lo_obj->check_step( ) = zif_test_sst=>mc_active.
lo_obj->execute( ).
ENDIF.
CATCH cx_sy_dyn_call_illegal_method. "Missing implementation
CATCH cx_root. "other exception
ENDTRY.
ENDMETHOD.
Execute
For the general execution of the logic, the first method can be integrated directly into a loop. When classes are found, they are executed directly in the loop if they are implemented and work correctly.
LOOP AT lcl_prog=>get_class( 'ZIF_TEST_SST' ) INTO DATA(ld_class).
lcl_prog=>start_impl( ld_class ).
ENDLOOP.
Conclusion
To find the right tables and content, you need a bit of research. For the execution of the implementations, you can directly address the interface methods, which the interface generally announces in the program.