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 ).
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:
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.
Ah... you're right. Sorry for the confusion. Correcting...
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.
You can make the ZCL_ABAP_DATE_CONSTANTS class non-final and use it like this:
Here we have another advantage. When inheriting in a local class, you can add program-specific constants.
That's great! I will add this to the original blog
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: