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