We all know that we can’t redefine Static Method. We’ll try to explore the reasoning and alternatives to achieve the similar behavior.
Redefinition is to over-ride the default implementation of the method in the subclass. This provides us the degree of polymorphism.
Reason – we can’t override Static Method
As we have seen in Overriding or Redefinition, it allows us to change the behavior of the instance method at runtime as long as we have redefined the method. At compile time, we use the Super Class to define the object. But which implementation system is going to take, would be only known at runtime. So, if have redefined the method, that implementation would be executed. But if we haven’t, than it would take implementation from Superclass.
Now, for static methods there isn’t any unknown factors at compile time. The method which we are trying to execute, it would be executed at the runtime as Static methods are independent of the instance components. That the reason we can’t use the instance attributes within static methods without using the instance of the class. Static methods are operable on their own.
With static methods, you call them by explicitly specifying the type on which they are defined. Which means, you directly call the implementation, which is not bound to any specific implementation of the instance object. This would be the reason, they can’t be overridden.
Lets say we have a logger method ZCL_LOG which we are using to log various stuff. Currently, this logger method only write to Application Log. Based on further requirement, we come to a point that we need to now log into a separate file or into DB table or an application log. Since we have the method as static we can’t just override that make it work.
ZCL_LOG static method
* CLASS zcl_log DEFINITION. PUBLIC SECTION. CLASS-METHODS: log. ENDCLASS. "zcl_log DEFINITION * CLASS zcl_log IMPLEMENTATION. METHOD log. * write into Application Log ENDMETHOD. "log ENDCLASS. "zcl_log IMPLEMENTATION
So here is the possible solution to avoid this situation.
Singleton + Helper Class
We will move out of the Static method. We’ll use method as a common interface which everyone can use to Log but we’ll create helper classes to actually do the logging.
* ZCL_LOG=>LOG changes – Add an importing parameter to decide Logger. Change the implementation to use the actual logger object to write into Log.
* Logger Class hierarchy – Create ZCL_LOGGER which can be inherited for individual Logging processing. CREATE_OBJECT is the method for Singleton implementation of the object.
The idea behind this is we can get multiple requests to write the log. So, we can call the ZCL_LOG=>LOG in many times for the same log type. Thus we need to implement Singleton. We can even enhance the singleton implementation to save more than one instance – one for each log type. Please read the comments for more clarification.
Log Class Hierarchy
* CLASS zcl_log DEFINITION. PUBLIC SECTION. CLASS-METHODS: log IMPORTING log_type TYPE char1. ENDCLASS. "zcl_log DEFINITION * CLASS zcl_log IMPLEMENTATION. METHOD log. DATA: lo_log TYPE REF TO zcl_logger. lo_log = zcl_logger=>get_object( log_type ). lo_log->write_log( logging_msg ). ENDMETHOD. "log ENDCLASS. "zcl_log IMPLEMENTATION * CLASS zcl_logger DEFINITION ABSTRACT . PUBLIC SECTION. METHODS: write_log ABSTRACT IMPORTING iv_log TYPE string. CLASS-METHODS: get_object " Singleton method IMPORTING IV_LOG_TYPE TYPE CHAR1 RETURNING value(ro_obj) TYPE REF TO zcl_logger. PRIVATE SECTION. CLASS-DATA: O_LOG TYPE REF TO ZCL_LOGGER. CLASS-DATA: V_SAVED_LOG_TYPE TYPE CHAR1. ENDCLASS. "zcl_logger DEFINITION * CLASS zcl_logger implementation. method get_object. IF v_saved_log_type NE iv_log_type. CASE iv_log_type. WHEN 'F'. lcl_class = 'ZCL_LOG_TO_FILE'. WHEN 'D'. * DB Logger WHEN OTHERS. * Application log - default ENDCASE. CREATE OBJECT ro_log TYPE ref to (lcl_class). o_log = ro_log. v_saved_log_type = iv_log_type. ELSE. ro_log = o_log. ENDIF. endmethod. endclass. * CLASS zcl_log_to_file DEFINITION INHERITING FROM zcl_logger. PUBLIC SECTION. METHODS: write_log REDEFINITION. ENDCLASS. "zcl_log_to_file DEFINITION * CLASS zcl_log_to_file IMPLEMENTATION. METHOD write_log. ENDMETHOD. "write_log ENDCLASS. "zcl_log_to_file IMPLEMENTATION
This boil downs to the fact that Static methods should be only used for Singleton Implementation and some time Utility class e.g. methods is CL_GUI_FRONTEND_SERVICES.