Skip to Content
11

Determine class name used for calling a static method

Hi all,

I know static methods cannot be redefined, but they can be called using a subclass as the 'calling class name'. Is it possible to determine the object type used for calling a static method?

For example, I have ZCL_SUPER with a static method HELLO and a subclass ZCL_SUB.

I can use ZCL_SUPER=>HELLO( ) or I can use ZCL_SUB=>HELLO( ).

Both will execute the same code (correct), but is it possible to tell the difference inside the HELLO method? SY-REPID will always show the superclass (also correct).

I've found some similar threads but none with a clear answer.

Any input appreciated,

Mike

Add a comment
10|10000 characters needed characters exceeded

Assigned Tags

Related questions

9 Answers

  • Best Answer
    Posted on Oct 23, 2015 at 06:41 AM

    I guess there is no simple solution. I expect that the compiler interprets the symbolic names ZCL_SUPER=> and ZCL_SUB=> in order to point to the method and forgets about it. Why should it keep the information? In fact I have a similar problem: Is there a simple way to find out the name of an actual parameter passed to a formal parameter inside a method? It isn't! I ended up in interpreting the call stack and parsing the calling code!

    Add a comment
    10|10000 characters needed characters exceeded

  • Posted on Apr 16, 2015 at 12:35 PM

    Hello!

    It's impossible to implement polymorphism using static methods in ABAP Objects. So, there is no difference between ZCL_SUPER=>HELLO( ) and ZCL_SUB=>HELLO( ) because you call exactly the same method in both cases

    Add a comment
    10|10000 characters needed characters exceeded

  • Posted on Apr 15, 2015 at 09:13 PM

    Hi Mike,

    I have no solution either, what if the caller is not an object?

    You can always evaluate the ABAP call stack (function module SYSTEM_CALLSTACK).

    regards,

    JNN

    Add a comment
    10|10000 characters needed characters exceeded

    • Thanks, but no then I'm stuck with the original problem of making every call explicit, or I might as well create statics in each subclass which call the superclass with the appropriate information.

      Both of which are exactly what I'm trying to avoid - the developer should be able to call my method in a subclass they create and not worry about the rest.

  • Posted on Apr 16, 2015 at 04:50 PM

    Hi Mike,

    Can I ask you why you want to know who called this method or by using what class name?

    You can also call the static method with an instance of the class. If you pass this instance to this method, you can use the object descriptor to know the type of the object. Generally if that is the object you are working on, you are more likely to use that object reference to call the static method.

    *
    CLASS lcl_super DEFINITION.
    PUBLIC SECTION.
    CLASS-METHODS: hello IMPORTING io_obj TYPE REF TO lcl_super.
    ENDCLASS. "lcl_super DEFINITION
    *
    CLASS lcl_sub DEFINITION INHERITING FROM lcl_super.
    ENDCLASS. "lcl_sub DEFINITION

    START-OF-SELECTION.
    "lcl_sub=>hello( ).
    DATA: lo_obj TYPE REF TO lcl_super.
    CREATE OBJECT lo_obj.
    lo_obj->hello( lo_obj ).
    CREATE OBJECT lo_obj TYPE lcl_sub.
    lo_obj->hello( lo_obj ).

    lcl_super=>hello( lo_obj ).

    *
    CLASS lcl_super IMPLEMENTATION.
    METHOD hello.
    WRITE: / 'Im called'.

    DATA: lo_objdesc TYPE REF TO cl_abap_objectdescr.
    DATA: lv_name TYPE string.
    lo_objdesc ?= cl_abap_objectdescr=>describe_by_object_ref( io_obj ).
    lv_name = lo_objdesc->get_relative_name( ).
    WRITE: lv_name.


    ENDMETHOD. "hello
    ENDCLASS. "lcl_super IMPLEMENTATION



    Regards,

    Naimesh Patel

    Add a comment
    10|10000 characters needed characters exceeded

    • Hi Naimesh,

      Agree, as I explained, a standalone factory class is exactly what my current best-but-not-perfect approach is. Anyone who creates a subclass of main superclass also has to add a corresponding method to the factory class. The method name itself thus becomes the key, and inside it they need to pass the class name to the superclass.

      If I add a further key into the equation then I'm back to where I might as well require all implementers of the class hierarchy to pass their subclass name in:

      ZCL_SUB7=>GET_INSTANCE( i_class = 'ZCL_SUB7' i_otherstuff = stuff ).

      I don't specifically want to hide the class name either. This is part of a larger framework where several developers will be creating subclasses, and these will be instantiated in various application scenarios. But in all cases the dev will know what they're trying to use.

      This is exactly the type of reason interfaces are preferable to inheritance, but in this case I'm stuck with it.

      Thanks,

      Mike

  • Posted on Apr 17, 2015 at 08:12 AM

    Hi Mike

    This is exactly one of the reasons why our team no longer works with static methods. Use an instance method instead, even if the coding is not (yet) object specific. This enables you also to use the runtime descriptor for classes to determine the actual name [cl_abap_classdescr=>get_class_name( me )]

    Regards

    Markus

    Check this example:

    class ZCL_SUPER definition
    public
    create public .
    public section.
    methods HELLO
    returning
    value(RV_NAME) type STRING .
    protected section.
    private section.
    ENDCLASS.

    CLASS ZCL_SUPER IMPLEMENTATION.
    METHOD hello.
    rv_name = cl_abap_classdescr=>get_class_name( me ).
    ENDMETHOD.
    ENDCLASS.

    class ZCL_SUB definition
    public
    inheriting from ZCL_SUPER
    create public .
    public section.
    protected section.
    private section.
    ENDCLASS.

    CLASS ZCL_SUB IMPLEMENTATION.
    ENDCLASS.

    Program:

    DATA: lo_obj TYPE REF TO zcl_sub.
    DATA: lv_name TYPE string.

    CREATE OBJECT lo_obj.

    lv_name = lo_obj->hello( ).

    WRITE lv_name.

    Add a comment
    10|10000 characters needed characters exceeded

    • Mike Pokraka Jacques Nomssi Nzali

      Hi Jacques,

      That is indeed the best 'proper OO' solution to the scenario, although in my case I will end up with several factory classes.

      In practice sadly it's too much work... I'm trying to create a framework which even junior developers want to use - a 3-lines-of-code job, which would ave been possible if a static method new it's calling mechanism.

      I like the abstract factory idea but I'm not going to sell this one to the masses who still think a class is a new-fangled replacement for a function group. 😔

      To all who replied: I have been pleasantly surprised and impressed by the overall level of good quality input on this thread, thanks to for much food for thought.

      Regards,

      Mike

  • Posted on Apr 16, 2015 at 10:39 AM

    Hi,

    Just a thought....

    If there was an ABAP equivalent to Java :

    this.getClass().getName();

    we can pass it as parameter .

    Regards.

    Add a comment
    10|10000 characters needed characters exceeded

  • Posted on Apr 16, 2015 at 10:53 AM

    I do not think it is possible. At least not with ABAP Objects "logic".

    There is no reference to caller object ("me" does not exist in static method).

    Maybe it is possible with some workaround. But for example SYSTEM_CALLSTACK would not help much with this problem, if you use local classes. I did not tried with global classes.

    Add a comment
    10|10000 characters needed characters exceeded

  • Posted on Apr 27, 2015 at 04:31 AM

    Hi Mike,

    As fas as I know, static method cannot be redefined in a subclass.

    Now, if super class is an abstract class, then that means that static method also is an abstract method. This implies that super class should not call this method at all as there is no implementation of this method inside super class.

    So, in a nutshell, if it is a usual super class, as the static methods cannot be redefined, so static method will always be called from super class only.

    If it is an abstract super class, then as you cannot redefine the static method inside sub class, so what is the use of having it in super class.

    Hope this helps!!!

    Regards,

    Richa

    Add a comment
    10|10000 characters needed characters exceeded

    • Hello Richa,

      Thanks for the input, but I think you misunderstood the problem.

      Now, if super class is an abstract class, then that means that static method also is an abstract method.

      Not correct. You can have code and define ordinary methods in an abstract class.

      So, in a nutshell, if it is a usual super class, as the static methods cannot be redefined, so static method will always be called from super class only.

      No, it can be called from outside the class, by other classes, reports, Web Dynpro apps. And that is precisely where my issue is. If I have ZCL_SUPER=>STATIC( ), I can also call ZCL_SUB=>STATIC( ) within my app.

      If it is an abstract super class, then as you cannot redefine the static method inside sub class, so what is the use of having it in super class.

      To provide a function that will be available to all subclasses.

      Regards,

      Mike

  • Posted on Oct 22, 2015 at 06:49 PM

    Hi Mike,

    This is a little bit old thread, but the question is interesting and also I am facing a similar problem.

    I am using a static attribute (class-data) named THIS_CLASS_NAME to hold the name of the current class/subclass. This static attribute is updated in the CLASS_CONSTRUCTOR of each subclass, like this:

    CLASS ZCL_SUB ...


    METHOD class_constructor.

    TYPES dummy TYPE REF TO ZCL_SUB.

    this_class_name = 'ZCL_SUB'.

    ENDMETHOD.

    As the class name assigned to the this_class_name attribute is a hardcoded text, if the subclass is renamed this text won't match the real subclass name. To reduce that chance, the TYPES clause will throw a syntax error when the subclass is renamed. Unluckily, it doesn't save us if the subclass is rename to ZCL_OTHER while there is now other class named ZCL_SUB.

    Now I can have generic constructors in the super class using the this_class_name attribute when required, as in:

    CLASS-METHODS build_this_way ...

    ...

    CREATE OBJECT result TYPE (this_class_name).

    ...

    or use it as argument invoking methods in specialized factory classes.

    Best regards,

    OdL

    Add a comment
    10|10000 characters needed characters exceeded

    • Ooops! Yes, you are totally right. I can't believe I didn't realize that!!...🤯

      I am working with a hierarchy of exception classes, but there is not a common root, because a branch is dynamic and the other isn't it. Besides that, the exception constructors are not editable...

      My goal is make them the easiest to construct and raise. e.g. without temporal variables (ABAP 7.00): Just one factory call and raise the exception. However, in this context -to avoid to repeat myself- I am forced to hardcode exception class names as strings, which are passed to more generic constructor routines. I whish there would be a way to pass a type as parameter, or a kind of 'me' variable referring somehow (maybe just by name) to the class where a static routine is running.

      Thank you.

Before answering

You should only submit an answer when you are proposing a solution to the poster's problem. If you want the poster to clarify the question or provide more information, please leave a comment instead, requesting additional details. When answering, please include specifics, such as step-by-step instructions, context for the solution, and links to useful resources. Also, please make sure that you answer complies with our Rules of Engagement.
You must be Logged in to submit an answer.

Up to 10 attachments (including images) can be used with a maximum of 1.0 MB each and 10.5 MB total.