This is a test message to test the length of the message box.
Login
ABAP OO Redefinition, Setter, Getter
Created by Software-Heroes

ABAP OO - Redefinition and Getter/Setter

In this article we look at the topic of redefinition and how getters and setters can help you with uniform interfaces.

Advertising

Today we will talk about redefinition and how it can help you build better classes and structure code more efficiently. As a second topic, we look at the use of getter and setter methods and how they make your interfaces better.

 

Redefinition

The redefinition is part of the inheritance of classes and can be used to overwrite inherited methods and thus provide them with new logic. It is important that the name of the method and the interface do not change. These remain stable and only a new flow logic is implemented. This means that the object remains stable when it is transferred to another interface, but the output and the data can change accordingly.

To do this, we define a simple class that should perform a calculation. The method takes a table of numbers and returns the corresponding sum. At this point you should note that your class is not FINAL, otherwise you can no longer inherit from it.

CLASS zcl_bs_demo_calculator DEFINITION PUBLIC CREATE PUBLIC.
  PUBLIC SECTION.
    TYPES:
      ts_numbers TYPE i,
      tt_numbers TYPE STANDARD TABLE OF ts_numbers WITH EMPTY KEY.

    METHODS:
      calculate
        IMPORTING
                  it_numbers       TYPE tt_numbers
        RETURNING VALUE(rd_result) TYPE i.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.


CLASS zcl_bs_demo_calculator IMPLEMENTATION.
  METHOD calculate.
    LOOP AT it_numbers INTO DATA(ld_number).
      rd_result += ld_number.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

 

Now we would like to implement a class that has the same interfaces as the first class, but the calculation is a little different. In this case we define a new class and inherit from our first class. Now all you have to do is redefine the CALCULATE method and then re-implement the logic. The interface remains stable and cannot be changed. So that you can reimplement the method locally, you have to create the method in the class and overwrite the method with the keyword REDEFINITION. You can then carry out the implementation again.

CLASS zcl_bs_demo_calc_redefinition DEFINITION PUBLIC CREATE PUBLIC 
 INHERITING FROM zcl_bs_demo_calculator.
  PUBLIC SECTION.
    METHODS:
      calculate REDEFINITION.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.


CLASS zcl_bs_demo_calc_redefinition IMPLEMENTATION.
  METHOD calculate.
    rd_result = 1.
    LOOP AT it_numbers INTO DATA(ld_number).
      rd_result *= ld_number.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

 

Now we can test the two classes. To do this, we define a console application and define the reference based on the original class and fill the numbers with 1-5 in order to have a basis for the calculation. Then we create an instance of the class and output the result to the console.

CLASS zcl_bs_demo_calc_usage DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.


CLASS zcl_bs_demo_calc_usage IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    DATA:
      lo_calculator TYPE REF TO zcl_bs_demo_calculator.

    DATA(lt_numbers) = VALUE zcl_bs_demo_calculator=>tt_numbers(
      ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 )
    ).

    lo_calculator = NEW zcl_bs_demo_calculator( ).
    out->write( |Original class: { lo_calculator->calculate( lt_numbers ) }| ).

    lo_calculator = NEW zcl_bs_demo_calc_redefinition( ).
    out->write( |Redefined class: { lo_calculator->calculate( lt_numbers ) }| ).
  ENDMETHOD.
ENDCLASS.

 

In the example we use the same reference variable to simulate the stable interface and create an instance of the class before we call the CALCULATE method. Here you can see the result of the calculation, the two differently defined methods were called.

 

Getter/Setter

Most classes also have attributes that are used within the class, but also provide data to the outside world. Such attributes can be defined as PUBLIC and thus made available via the object. This means that a user can access the attribute at any time, read the data, but also change it. This behavior is not always desired and has a decisive disadvantage, you no longer have any influence on the attribute before it is given to the outside world and this must remain stable at all times (data type).

Let's take a look at a small example of a class that has a table that accepts messages that are added via the method ADD_MESSAGE.

CLASS zcl_bs_demo_public_data DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    DATA:
      mt_messages TYPE string_table.

    METHODS:
      add_message
        IMPORTING
          id_message TYPE string.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.


CLASS zcl_bs_demo_public_data IMPLEMENTATION.
  METHOD add_message.
    INSERT id_message INTO TABLE mt_messages.
  ENDMETHOD.
ENDCLASS.

 

In this fictional example we are adding various messages to the class and in the middle of this process we are deleting the messages. This is to simulate that while we were executing another piece of source code initialized the class. All reports up to then are lost and the result could be falsified.

DATA(lo_public_data) = NEW zcl_bs_demo_public_data( ).
lo_public_data->add_message( `Message 1` ).

CLEAR lo_public_data->mt_messages.

lo_public_data->add_message( `Message 2` ).
lo_public_data->add_message( `Message 3` ).

 

To prevent this, we can change the visibility of the attribute and set it to PROTECTED or PRIVATE. This means that it can no longer be changed from the outside and our messages are safe from unwanted changes. How do we get the messages from outside? For this we implement a getter, this is a method that starts with GET_, usually has the name of the attribute after that and has a returning parameter that returns the attribute. The changed class could now look like this:

CLASS zcl_bs_demo_private_data DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    METHODS:
      add_message
        IMPORTING
          id_message TYPE string,

      get_messages
        RETURNING VALUE(rt_result) TYPE string_table.

  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA:
      mt_messages TYPE string_table.
ENDCLASS.


CLASS zcl_bs_demo_private_data IMPLEMENTATION.
  METHOD add_message.
    INSERT id_message INTO TABLE mt_messages.
  ENDMETHOD.


  METHOD get_messages.
    rt_result = mt_messages.
  ENDMETHOD.
ENDCLASS.

 

Our messages MT_MESSAGES are now protected against unwanted changes. A setter, on the other hand, is a method that begins with SET_, followed by the name of the attribute and has an importing parameter. This method sets the attribute in the class with a new value.

Getters and setters have several advantages when using them:

  • Implementation of additional check and filter code
  • Protection of the attributes from unwanted changes
  • Uniform and stable interfaces
  • Opportunities to intervene in the process

 

Read Only

In addition to the getter and setter methods, there is also another way of working with public attributes and protecting them from access at the same time. You can also assign the READ-ONLY addition to the attribute so that the attribute is only released for read access. In addition the changed class from the previous section:

CLASS zcl_bs_demo_readonly_data DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    DATA:
      mt_messages TYPE string_table READ-ONLY.

    METHODS:
      add_message
        IMPORTING
          id_message TYPE string.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.


CLASS zcl_bs_demo_readonly_data IMPLEMENTATION.
  METHOD add_message.
    INSERT id_message INTO TABLE mt_messages.
  ENDMETHOD.
ENDCLASS.

 

If you now try to write to the attribute, you will get an error while the compile is running and you can no longer activate your code. Here is the message from Eclipse:

 

The attribute is now protected against write access, but you also lose the advantages of the getter and setter methods and can no longer intervene in the code or implement your own checks. We only recommend this variant to a limited extent.

 

Conclusion

Today it was about the redefinition of methods in order to be able to implement different logic in the same methods and to create the same classes with different behavior. You have also learned how to efficiently manage your attributes in a class while maintaining full control over your data.


Included topics:
OOABAP OORedefinitionGetterSetter
Comments (0)
Advertising

ABAP OO - Chaining and casting

Category - ABAP

This article is about the chaining of method and object calls, we would also like to explain the background to casting to you.

08/20/2021

ABAP OO - Data Access Object (DAO)

Category - ABAP

In this article we take a look at the DAOs, what you can do with them and how they support you.

07/23/2021

ABAP OO - Constant interface

Category - ABAP

The use of constants in object-oriented programming is standard for most classes. Today we're going to show you a simple example of overarching objects.

07/16/2021

ABAP OO - Exception classes

Category - ABAP

Today we look at the different exception classes and how you can create and use your own exception classes.

07/09/2021

ABAP OO - Exception Handling

Category - ABAP

What about error handling in object-oriented programming? We want to address this question in this article.

07/02/2021