Skip to Content
Technical Articles

ABAP – short cuts to central constant classes

This is a follow-up to my last post, where I talked about central classes to keep type declarations for an application.

Of course, I do the same thing for constants. I have for instance a class to keep some very central date constants:

class ZCL_ABAP_DATE_CONSTANTS definition
  public
  final
  create public .

public section.
  constants maximum_date type d value '99991231'.
  constants first_day_of_year type string value '0101'.
  constants last_day_of_year type string value '1231'.
  constants minimum_date type d value '00010101'.
protected section.
private section.
ENDCLASS.

Unfortunately things do not work as they do for type classes. I found out, that you can access constants of a class only using the public class and the static operator =>:

* Working
call_method( zcl_abap_date_constants=>maximum_date ).

However, if I create a short cut using a variable, it doesn’t work (although this works for the types – strange):

data date_constants type ref to zcl_abap_date_constants.
data common_types type ref to zcl_abap_common_types.

" Working for types
data binary_table type common_types->binary_table.

" Not working for constants --> syntax error
call_method( date_constants->maximum_date ).

A workaround could be instantiate the class using the variable:

class app definition.

  public section.
    methods constructor.
    methods main.

  private section.
    data date_constants type ref to ZCL_ABAP_DATE_CONSTANTS.
endclass.

class app implementation.
  method constructor.
    date_constants = new #( ).
  endmethod.

  method main.
    cl_demo_output=>display( date_constants->maximum_date ).
  endmethod.
endclass.

But as Maxim Freck pointed out, it’s also possible to keep the constant class abstract and inherit a local class from it:

class constants definition final inheriting from zcl_abap_date_constants.
endclass.

* Working
call_method( constants=>maximum_date ).
10 Comments
You must be Logged on to comment or reply to a post.
  • Hi,

    As far as I know, you don’t need to instantiate a class in order to refer to its constants.

    The constants are defined as static members.

    i.e. ZCL_ABAP_DATE_CONSTANTS=>MAXIMUM_DATE should work in your case.

    • You are right, but the goal is, to get rid of the needlessly long ZCL_ABAP_DATE_CONSTANTS=> and use date_constants-> instead.

      When the constant class belongs to your application, you can even shorten again:

      class zcl_name_of_application_constants definition.
        public section.
          constants character_a type c length 1 value 'A'.
      (...)
      
      class zcl_name_of_application_frontend definition.
        private section.
          data constants type ref to zcl_name_of_application_constants.
      (...)
      
      method constructor.
        constants = new #( ).
      
      (...)
      
      method main.
       call_something( constants->character_a ).

      Do you get the point?

      • Well, that is correct, but that is another point – subjective one, I must say, but I see no harm with it.

        I commented earlier because you have mentioned that class constants aren’t static, which is incorrect.

         

      • Shai is pointing out that the statement in the blog “you can not access the constants of a class without instantiating it” is inaccurate. You might want to edit the blog text and note that you’re instantiating not because you must but because you prefer.

        Otherwise it’s misleading. I haven’t had such issues with the class constants, so was very confused until I scrolled to these comments.

        Thank you!

  • Hi Jörg Krause,

    Thank you for your contribution and I think the idea with constants as classes is better than with interfaces. This is my opinion.

    Maybe you could also use the Singleton pattern here. Instead of creating the class instance from outside.

    I think here the personal preference plays a big role how one does it now.

  • Hi,

    You can make the ZCL_ABAP_DATE_CONSTANTS class non-final and use it like this:

    class constants definition final inheriting from zcl_abap_date_constants.
    endclass.
    
    * Working
    call_method( constants=>maximum_date ).

    Here we have another advantage. When inheriting in a local class, you can add program-specific constants.

     

  • Another option is to use central constant interace, add it to your class and define aliases.

    More work, but this way you can use access the constants directly in your class via short names.

    • I did this in former days. What I dislike here, is the need to rework the alias definitions as soon as you add new constants to the interface. Another annoying thing is the noisy code it produces with all these aliases statements (visible in the source code view of the class). Then, if you use more than one constants interface, the names of the constants must be unique. Using classes, I can distinguish them via class names:

      class zcl_status_text_constants definition.
        public section.
          constants released type j_txt04 value 'FREI'.
      endclass.
      
      class zcl_status_id_constants definition.
        public section.
          constants released type j_stat value 'I0002'.
      endclass.
      
      class status_texts definition inheriting from zcl_status_text_constants.
      endclass.
      
      class status_ids definition inheriting from zcl_status_id_constants.
      endclass.
      
      (...)
      if check_status( status_ids=>released ).
        output_status( status_texts=>released ).
      endif.