Skip to Content
Technical Articles
Author's profile photo Nelson Miranda

Classes in ABAP

Classes are fundamental structures that we need to understand and master to model entities.

A class can represent anything; a document, a vehicle, animal, or anything that has traits and behaviours.

Classes in ABAP are coded in two steps: first of all, you code the definition part and then the implementation part.

The definition part is the place where you define all the data and methods that are going to be used in the class.

Here you must specify the public, private, and protected sections also they have to be placed in the order you see in the code otherwise you will a syntax error.

The following code shows the structure of a class:

CLASS <Name of the class> DEFINITION.
PUBLIC SECTION.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.

CLASS <Name of the class> IMPLEMENTATION.
ENDCLASS.

 

For a better illustration let’s create complete example to show more details of a class.

Please create a new program and name it ZCLASS and paste the following code.

report  zclass.

class cl_animal definition abstract.
  public section.
    methods: constructor importing i_name type string, " Visible to everyone
             make_a_sound,
             my_name_is,
             get_type,
             introduce_me.

  protected section. " Visible only in child classes
    data p_class type string.

  private section. " Visible only internally
    data p_name type string.
endclass.

class cl_animal implementation.
  method constructor.
    p_name = i_name.     " p_name was defined already in the definition part of the class as private
    p_class = 'Unknown'. " p_class was defined already in the definition part of the class as protected
  endmethod.

  method make_a_sound.
    write 'Nothing'.
  endmethod.

  method my_name_is.
    write: / 'My name is: ', p_name.
  endmethod.

  method get_type.
    write: / 'I''m type of: ', p_class.
  endmethod.

  method introduce_me.
    me->my_name_is( ). " The keyword 'me' is used to specify class member. Is the equivalent of the keyword 'this' in C#
    make_a_sound( ).
    get_type( ).
  endmethod.
endclass.

class cl_dog definition inheriting from cl_animal.
  public section.
    methods: constructor importing i_dog_name type string,
             make_a_sound redefinition. " Change the behaviour of the method. Reimplement the code.
endclass.

class cl_dog implementation.
  method constructor.
    super->constructor( i_dog_name ). " Initialize the constructor and internally pass the parameter to the abstract class
    p_class = '"Dog"'.                " This is the protected member which is visible only in child classes
  endmethod.

  method make_a_sound.
    write: / 'My sound is:', 'Woof, woof'.
  endmethod.
endclass.

class cl_cat definition inheriting from cl_animal.
  public section.
    methods: constructor importing i_cat_name type string,
             make_a_sound redefinition.
endclass.

class cl_cat implementation.
  method constructor.
    super->constructor( i_cat_name ).
    p_class = '"Cat"'.
  endmethod.

  method make_a_sound.
    write: / 'My sound is:', 'Meow, meow'.
  endmethod.
endclass.

class cl_animal_factory definition.
  public section.
    class-methods create_animal importing i_animal type i returning value(r_animal) type ref to cl_animal. " Class method, in C# this is called a static method
endclass.

class cl_animal_factory implementation. " Factory pattern
  method create_animal.
    case i_animal.
      when 1.
        data dog type ref to cl_dog.
        create object dog exporting i_dog_name = 'Sparky'.
        r_animal = dog. " It is returned a cl_dog instance.
      when 2.
        data cat type ref to cl_cat.
        create object cat exporting i_cat_name = 'Fluffy'.
        r_animal = cat. " It is returned a cl_cat instance.
      when others.
    endcase.
  endmethod.
endclass.

class cl_introducer definition.
  public section.
    class-methods introduce importing i_animal type ref to cl_animal. " Here the method receives a cl_animal type parameter
endclass.

class cl_introducer implementation.
  method introduce.
    if i_animal is not initial.
      i_animal->introduce_me( ).
    else.
      write / 'I''m nothing'.
    endif.
  endmethod.
endclass.


start-of-selection.
  data wa_animal type ref to cl_animal.

  wa_animal = cl_animal_factory=>create_animal( 1 ).
  cl_introducer=>introduce( wa_animal ). " The i_animal parameter is implicitly specified. Useful when is only one parameter.
  write /.

  wa_animal = cl_animal_factory=>create_animal( 2 ).
  cl_introducer=>introduce( i_animal = wa_animal ). "  The i_animal parameter is explicitly specified and is necessary its use when is more than one paramter.
  write /.

  wa_animal = cl_animal_factory=>create_animal( 3 ).
  cl_introducer=>introduce( wa_animal ).

By definition, classes can be created as normal, abstract, and inherited. For example:

For any given class is only necessary the following:

class myclass definition.
endclass.

For an abstract class the code is:

class myclass definition abstract.
endclass.

This kind of class cannot be instantiated.

And for an inherited class or subclass the code is:

class myclass definition inheriting from abstractclass.
endclass.

The public section is the place where you declare information that is visible outside the class.

The private section has members that are internal and can’t be exposed outside the class even within subclasses.

The protected section has information that is exposed or is visible only internally and along with all the child classes.

In every section, you can specify instance data and methods and also class data and methods.

The difference between instance members and class members is that for the first ones it is necessary to create the object (we’ll get there soon) to use those members and in the second ones is not necessary the instantiation, we can use them directly from the class with a special sign (=>) and for the other instance data and methods it is used the (->) sign.

class cl_animal definition abstract.
  public section.
    methods: constructor importing i_name type string, " Visible to everyone
             make_a_sound,
             my_name_is,
             get_type.

  protected section. " Visible only here and in child classes
    data p_class type string.

  private section. " Visible only internally
    data p_name type string.
endclass.

The implementation part is used to code the methods. Here you code the behavior of the class and you can see that none of the members including the parameters are presented and that’s because they were already defined previously in the definition part of the class.

class cl_animal implementation.
  method constructor.
    p_name = i_name.     " p_name was defined already in the definition part of the class as private
    p_class = 'Unknown'. " p_class was defined already in the definition part of the class as protected
  endmethod.

  method make_a_sound.
    write 'Nothing'.
  endmethod.

  method my_name_is.
    write: / 'My name is: ', p_name.
  endmethod.

  method get_type.
    write: / 'I''m type of: ', p_class.
  endmethod.
endclass.

The next part of the code consists of how you can inherit classes.

This is a powerful concept because you get the functionality that already exists and depending on the definition, it is possible to change the behavior of a method.

class cl_dog definition inheriting from cl_animal.
  public section.
    methods: constructor importing i_dog_name type string,
             make_a_sound redefinition. " Change the behaviour of the method. Reimplement the code.
endclass.

class cl_dog implementation.
  method constructor.
    super->constructor( i_dog_name ). " Initialize the constructor and internally pass the parameter to the abstract class
    p_class = '"Dog"'.                " This is the protected member which is visible only in child classes
  endmethod.

  method make_a_sound.
    write: / 'My sound is:', 'Woof, woof'.
  endmethod.
endclass.

The method ‘make_a_sound’ was overrwritten, or better said, overridden to act differently from the original class. The same applies to the ‘cl_cat’ class.

One powerful trait about classes is that we can make more with less and we can also create a common interface to make classes of the same type could act differently.

This concept is called ‘polymorphism’ and a good example of this is the following implementation using the Factory pattern:

class cl_animal_factory definition.
  public section.
    class-methods create_animal importing i_animal type i returning value(r_animal) type ref to cl_animal. " Class method, in C# this is called a static method
endclass.

class cl_animal_factory implementation. " Factory pattern
  method create_animal.
    case i_animal.
      when 1.
        data dog type ref to cl_dog.
        create object dog exporting i_dog_name = 'Sparky'.
        r_animal = dog. " It is returned a cl_dog instance.
      when 2.
        data cat type ref to cl_cat.
        create object cat exporting i_cat_name = 'Fluffy'.
        r_animal = cat. " It is returned a cl_cat instance.
      when others.
    endcase.
  endmethod.
endclass.

class cl_introducer definition.
  public section.
    class-methods introduce importing i_animal type ref to cl_animal. " Here the method receives a cl_animal type parameter
endclass.

class cl_introducer implementation.
  method introduce.
    if i_animal is not initial.
      i_animal->introduce_me( ).
    else.
      write / 'I''m nothing'.
    endif.
  endmethod.
endclass.

Here we define a class which creates different types of instances of cl_animal class and the advantage on this is that we can use the cl_introduce class to act on any child class of cl_animal type.

The purpose is to not change the interface and use a common procedure that is going to be prepared to function on these classes.

Finally the code ends like this:

start-of-selection.
  data wa_animal type ref to cl_animal.

  wa_animal = cl_animal_factory=>create_animal( 1 ).
  cl_introducer=>introduce( wa_animal ). " The i_animal parameter is implicitly specified. Useful when is only one parameter.
  write /.

  wa_animal = cl_animal_factory=>create_animal( 2 ).
  cl_introducer=>introduce( i_animal = wa_animal ). "  The i_animal parameter is explicitly specified and is necessary its use when is more than one paramter.
  write /.

  wa_animal = cl_animal_factory=>create_animal( 3 ).
  cl_introducer=>introduce( wa_animal ).

Notice that for the ‘introduce’ class-method of class ‘cl_introducer’ you can specify implicit or explicitly the parameter. When methods have more than one parameter is necessary to explicitly specify the parameters.

The output of the program is the following:

My name is:  Sparky
My sound is: Woof, woof
I'm type of:  "Dog"

My name is:  Fluffy
My sound is: Meow, meow
I'm type of:  "Cat"

I'm nothing

This was a simple example where it is shown how to code classes in ABAP.

From here we can make more complex hierarchies and represent our data with their actions and behaviours.

Hope you enjoyed the article and if you need to practice more on this topic you can use this example in your cloud trial account.

You can check the code in my gtihub repository.

Best regards.

Assigned Tags

      12 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Bärbel Winkler
      Bärbel Winkler

      Thanks for this ABAP OO example which is (still) exactly the kind of explanation I need whenever I get confused about what is what with OO!

      It'll also make for a good example when trying to explain the basic concepts to others.

      Cheers

      Bärbel

      Author's profile photo Matthew Billingham
      Matthew Billingham

      Anything that helps people get started with OO is a good thing.

      Author's profile photo Vijay Ravidran
      Vijay Ravidran

      Beautifully written article with detailed explanations and examples.

      This deserves a spot in my bookmarks! Well done!

       

       

      Author's profile photo Paul Hardy
      Paul Hardy

      I would also like to thank you for explaining what a class is to those ABAP programmers who do not yet know.

      Such concepts have been available in ABAP since the year 2000, twenty years ago.

      Even BEFORE 2000 in ABAP there were OO concepts e.g. the workflow business objects.

      As yet, very few ABAP programmers use classes and such "new fangled" ideas. You may think I am being sarcastic but I am not. I have ben trying to convince people to move to OO programming in ABAP for a very long time now, over ten years now, and I am getting NOWHERE.

      I feel this is a shame. In an ideal world at this point you would ideally not need to to have to write a blog on SDN explaining what a class is. everyone should know by now, after twenty years.

      Yet they do not. Many people think they are a strange form of Function Module.

      Cheersy Cheers

      Paul

       

       

       

       

      Author's profile photo Matthew Billingham
      Matthew Billingham

      I've been debugging some SAP code that must be post 7.50... and it's using forms. I could cry.

      At least I've not seen a FIELD GROUP for over fifteen years.

      Author's profile photo Bärbel Winkler
      Bärbel Winkler

      Lucky you, Matt! I recently created a new program instead of changing a Z-program which started it's life as a rather ill-conceived copy of a query program several years ago. FIELD-GROUPS and other constructs, which are now deemed obsolete, abounded in that program!

      Cheers

      Bärbel

      Author's profile photo Consulta Mensajes
      Consulta Mensajes

      Thank you nelson for this great article. It is very clear and beneficial for

      OOP developers.

      Author's profile photo Nabheet Madan
      Nabheet Madan

      Thanks for posting about this. The war to adopt OO ABAP goes on. I still see majority of developers who are still continuing the old way!

      I hope with coming of SAPUI5 and people have to learn Javascript some changes in the way we code in ABAP shall change for good, Even creation of OData services forces you to follow the OO pattern but many of us still create Z FM's:)

      I hope we change  our approach soon and move towards OO,TDD,BDD,FP and what not.

       

      Thanks

      Nabheet

      Author's profile photo Radoslaw Chudziak
      Radoslaw Chudziak

      Check out the discussion forum of openSAP course on ABAP RAP. People crying that they did ABAP for 15 years and now they have to learn CDS/RAP/SAPUI5. And that RAP is so complex and hard. I believe everything is hard when you are just starting off. Even ABAP!

      People wish all they would hvae to do was procedural ABAP from hire to retire and not waste time learning anything new.

      Author's profile photo Nelson Miranda
      Nelson Miranda
      Blog Post Author

      I use OOP as much as I can when I program in ABAP however I share a little of the frustration of some developers checking RAP lately.

      RAP is like starting over. It’s too much to learn, at least at the beginning, however, it’s the way it is, I mean, I think people before R/3 felt like the same frustration during the transition.

      Just a hint; in RAP first you make the table, then the business object, then the projection view, then the behavior definition and implementation (managed (greenfield) or unmanaged (brownfield) scenario), then the metadata, then the service definition, then service binding, then access control.

      Add to this CDS, EML (Entity Manipulation Language), annotations, Fiori, SAPUI5, TDD, and more.

      All these concepts rely mostly on OOP, so if you are not used to this paradigm you will have a hard time learning before producing solutions in ABAP.

      Even for me is too much but it’s a matter of time.

      Check this mission Develop a Fiori App Using the ABAP RESTful Programming Model (Managed Scenario) to find out or enroll in the ‘Building Apps with the ABAP RESTful Application Programming Model’ course from openSAP.

      Author's profile photo Radoslaw Chudziak
      Radoslaw Chudziak

      I agree it is complex and a lot to take on. But all this can be learned one step at a time. Starting with CDS views as they are a cornerstone technology in S4. Lots of people are still on ECC, so they should start learning these new technologies now, before they move to S4 as it will take a lot of time.

      What I don't agree with, is people's attitude. 'We always did ABAP, why change it, I can't be bothered learning anything new, it's out of my comfort zone'.

      Author's profile photo Gerson Cordon
      Gerson Cordon

      Excellent explanation Nelson. I am not programmer but the way you wrote it, I think I could fully understand the concept !!