Hello my fellow ABAPers(others are welcome too!).

When first facing object orientation in ABAP, some of you have probably tried to do something like this (at least I did..):

CLASS lcl_fs_test DEFINITION.

  PRIVATE SECTION.

    DATA: priv TYPE c LENGTH 3 VALUE ‘foo’.

ENDCLASS.

START-OF-SELECTION.

  DATA: o_access TYPE REF TO lcl_fs_test.

  FIELD-SYMBOLS <priv> TYPE any.

  CREATE OBJECT o_access.

  ASSIGN (‘O_ACCESS->PRIV’) TO <priv>.

CLASS lcl_fs_test IMPLEMENTATION.

ENDCLASS.

and it resulted in short dump πŸ™ .

Well, some days ago I was going to work when I had an idea, what would happen if we tried to access the reference of the private attribute instead?

REPORT  zfaw_test_reference.

CLASS lcl_reference_test DEFINITION.

  PUBLIC SECTION.

    METHODS:

    get_private_attribute RETURNING value(private_var) TYPE char3,

    get_private_by_ref EXPORTING data TYPE REF TO data.

  PRIVATE SECTION.

    DATA: private_variable TYPE c LENGTH 3 VALUE ‘foo’.

ENDCLASS.

CLASS lcl_reference_test IMPLEMENTATION.

  METHOD get_private_attribute.

    private_var = me->private_variable.

  ENDMETHOD.

  METHOD get_private_by_ref.

    GET REFERENCE OF me->private_variable INTO data.

  ENDMETHOD.

ENDCLASS.

DATA: reference_tester TYPE REF TO lcl_reference_test,

      private_ref      TYPE REF TO data,

      private_content  TYPE char3.

FIELD-SYMBOLS: <private_content> LIKE private_content.

START-OF-SELECTION.

  CREATE OBJECT reference_tester.

  private_content =   reference_tester->get_private_attribute( ).

  WRITE: / ‘Value before: ‘ , private_content.

  reference_tester->get_private_by_ref( IMPORTING data = private_ref ).

  ASSIGN private_ref->* TO <private_content>.

  <private_content> = ‘bar’.

  private_content =   reference_tester->get_private_attribute( ).

  WRITE: / ‘After get by reference: ‘ , private_content.

And this works!

Does this break any OO concept? I have no idea, I’m a newb!

What I know is, we have to create a special method to allow this kind of changes and so, our intent IS to allow this kind of behaviour!

But without the proper getters/setters we won’t control how the attribute is changed, anyone can change the attribute from anywhere in the program, moreover, if we allow this kind of behaviour in our class why not declare the variable as public and save us all the trouble.

I don’t know what I should think of this, I just find it interesting and I wanted to share =].

To report this post you need to login first.

22 Comments

You must be Logged on to comment or reply to a post.

  1. Suhas Saha

    Does this break any OO concept?

    Yes, it does and IMO a major one at that – ENCAPSULATION πŸ™‚

    I faced the same thing today at work. I was passing a field-symbol ASSIGNed to a pvt. attribute of my class to the changing param of CL_SALV_TABLE=>FACTORY( ) & it gave a runtime error. Reason – The pvt. attribute could not be changed. (Same with PUBLIC READ-ONLY)

    Then i tried with data reference & it worked 😯 Instead of making conclusions, straightaway i dived into the ABAP documentation and found this –

    If references are set using GET REFERENCE, permission to access the data object in question is only checked at the position of the statement. After that, the references can be passed on to any destination and the associated data objects can be accessed from any position using the references. To prevent access to private and read-only attributes using references outside classes, do not publish references to these attributes externally. A constant or read-only input parameter, however, can never be made modifiable by passing its reference.

    Refer – http://help.sap.com/abapdocu_740/en/abapget_reference.htm

    I thought –

    Hey i’m not publishing the data outside my class, just to the ALV class πŸ˜‰ I don’t need to change my code.

    The refactoring effort would have been too high anyway, so i left this dirty lil’ trick stay πŸ˜›

    BR,

    Suhas

    (0) 
    1. Adriano S. Campanhola Post author

      Yea, it’s pretty obvious that it breaks encapsulation!

      What I mean is. Is this an OO concept? in other languages, can you pass the reference and be happy forever and ever?

      About the documentation, that’s really interesting, but IMO, that shouldn’t be allowed at all =)

      (0) 
      1. Suhas Saha

        Does this break any OO concept? I have no idea, I’m a newb!

        I don’t think that you are a newbie, you sound like a pro 😎

        that shouldn’t be allowed at all =)

        +1. I’m not an OO purist, i can live with the fact that this behavior is known & documented πŸ™‚

        BR,

        Suhas

        (0) 
  2. Nope Sanducal

    I think OOP is break when speaking of “private could not be influenced outside of its class”, but for me, remember the added OO feature of SAP like the “Friends”? I think, this could be somewhat I unique SAP way of defining its own OO concept at least in ABAP. Thus, “GET REFERENCE” is the added feature here and it is on the programmer discretion if he/she wants to expose the private attributes of his/her class. πŸ™‚

    (0) 
    1. Adriano S. Campanhola Post author

      Hi Nope,

      I agree with you, the friends addition exists in other languages, but it is a choice of the developer to use it. Since encapsulation is one of the main concerns in OOP and the ‘friends’ addition really ruins it.

      As I said in the blog, there is no real need for the getter with reference, just make your attribute public!

      Unless you want to enhance a standard class… in this case you can change any private components as you wish πŸ˜‰

      (0) 
      1. Christoph Hermanns

        Hi Adriano,

        yes, friends can be used for cheating. But they can also be used for implementing proper factories for example: class/classes of the objects to be created by the factory are marked as PRIVATE CREATE. The factory-class is a friend of this class/these classes and is therefore the only one being able to create instances of this class/these classes. That’s why you implement a method called CREATEOBJECT (or something like this) which creates (and returns) an object within the factory-class. Meanwhile the factory-class keeps track of the instantiation process. When not using the friend concept in this context it is still possible for all to create such instances. So this would be one usefull context for using friends. So as you already said: It depends on the developer to use elements of a programming language for cheating or proper purposes.

        Best regards,
        Christoph.

        (0) 
        1. Adriano S. Campanhola Post author

          I never thought about that, I always created my factory methods and got really angry when someone used the regular way to instantiate the class! I’ll be sure to use that!

          Thanks Christoph!

          (0) 
        2. Custodio de Oliveira

          Christoph Hermanns wrote:

          they can also be used for implementing proper factories for example: class/classes of the objects to be created by the factory are marked as PRIVATE CREATE. The factory-class is a friend of this class/these classes and is therefore the only one being able to create instances of this class/these classes. That’s why you implement a method called CREATEOBJECT (or something like this) which creates (and returns) an object within the factory-class. Meanwhile the factory-class keeps track of the instantiation process.

          This is how persistent classes work, by the way.

          (0) 
      2. Lucas TΓ©treault

        Adriano S. Campanhola wrote:

        Unless you want to enhance a standard class… in this case you can change any private components as you wish πŸ˜‰

        How do you think this will be possible?

        I’m assuming you’re thinking of sub-classing a standard class and creating your get reference method? Except that won’t work because you don’t have access to private attributes in sub-classes.

        So this ‘trick’ is only useful when you can modify the class and like you said, then it just makes more sense to make it public or use getters + setters.

        (0) 
        1. Custodio de Oliveira

          No, I assume he’s thinking of creating an enhancement in the standard class and create a new method get_<private_attribute>. It definitely works, I’ve done a few times (not recommended πŸ˜‰ )

          (0) 
  3. Christoph Hermanns

    In my opinion the formulation “private could not be influenced outside of its class” is not telling the total truth: Of course it is possible to influence a private attribute from outside. The difference to a public attribute is, that it is not possible in a direct way (by accessing the private attribute by it’s name) but by calling public methods of the class instead. In these methods you can modify the attribute’s value at libitum. And the corresponding getter method will return the modified value. So it’s up to you to handle the use of a private attribute – even by using references. Hence, in other OO-languages such as c++ this is also possible.

    Best regards,

    Christoph.

    (0) 
  4. Matthew Billingham

    The correct way to do it is to write a setter and a getter for the private attribute. That way you can control what happens to it. For example, in the setter, you could put some validation on what’s supplied.

    (0) 
    1. Adriano S. Campanhola Post author

      Yes, I agree with you. All I wanna show here is that the ‘private barrier’ is not impenetrable, you can change an attribute at will if you create the right method =], and again, there is no point in this, you can just make the attribute public if you’re going to do something like I did in the blog!

      BR

      (0) 

Leave a Reply