Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Abstract Class and class-method

asuji20
Explorer
0 Kudos

Hi,

I have been reading various posts on OOPS ABAP and below is the inference i have got so far.

We go for abstract classes when we have some common functions and some unique functions respective to implementing class.

Interfaces can also achieve what is mentioned above about abstract classes but we mainly go for it for polymorphism and when there is no need for common functions/global functions between implementing classes

My question is ?? what i told about abstract class can also be achieved using class-methods, class-data (for global functions) and normal class inheritance (for redefining unique functions), then why should we go for abstract classes.

Moreover, we have a disadvantage with abstract classes, that all the implementing classes must redefine all the abstract methods. We add a new abstract method to an abstract class, we need to define it in all implementing classes.

Then why are we not sticking with using class-method and normal inheritance and instead go for abstract classes?

Even interfaces have this disadvantage, but it is the only way for polymorphism.

Also, the global/common methods of an abstract class can be redefined where as class-methods cannot be, helping us achieve OO Pardigm better.

Could anyone please help me understand this, please forgive me if i am wrong anywhere.

1 ACCEPTED SOLUTION

asuji20
Explorer
0 Kudos

Hello All,

Thank you so much, the below try out was what actually made me doubt why and when do we really need abstract class ( programming wise, not conceptual )

A scenario

abstract_class

method display importing info FINAL   "common method

abstract method "get info"                     "method for redefinition

"if we add new abstract method we need to redefine in all classes - Issue

class1 inheriting from abstract_class

redefine method "get info" to "get name info"

class2 inheriting from abstract_class

redefine method "get info" to "get age info"

class_trigger

class-method call_all importing classimp type ref to abstract_class

call method classimp->get_info()

call method classimp->display()

endmethod

create objects class1, class2

class_trigger->call_all ( class1 ).

class_trigger->call_all ( class2 ).

Now, I can do the same using class-method and normal redefinition

Main_class

class-method display importing info  "common method

method "get info"                               ""method for redefinition

class1 inheriting from main_class

redefine method "get info" to "get name info"

class2 inheriting from main_class

redefine method "get info" to "get age info"

class_trigger

class-method call_all importing classimp type ref to abstract_main

call method classimp->get_info()

call method classimp->display()

endmethod

create objects class1, class2

class_trigger->call_all ( class1 ).

class_trigger->call_all ( class2 ).

i think that's what i am trying to know, why go through the trouble of creating abstract classes methods and compel implementing classes to redefine them all.

@Frank kirck , could you please help me understand this scenario and why abstract is needed

12 REPLIES 12

Former Member
0 Kudos

Puhhh, where to start?

In the usual case you use abstract classes i.e. abstract methods only for these cases, where you really want to redefine it always in the sub classes. It's not needed to define all methods as abstract, you can implement methods also in an abstract class.

Of course you can also avoid a redefinition of an already implemented method by using FINAL.

Interfaces are good to hide implementations (open-close-principle) and to seperate concerns. They are also very good for dependency injections in well layered applications.

If you say, you can implement the functionalities also as static methods, then it sounds like you need in fact helper or utility classes. So you should not take inheritance as solution, but delegation.

0 Kudos

Hello Armin,

Thank you.

"FINAL" is a great solution to prevent redefinition of abstract classes' common methods, but i still don't understand why were abstract classes formed when we could do it all using simple static methods and normal redefinition of a super classes' methods.

Can you explain more about "it sounds like you need in fact helper or utility classes. So you should not take inheritance as solution, but delegation"

0 Kudos

Hi Madhu,

in short, because you often can not. Consider this example in my pseudo language:

class Primitive {

     abstract draw(canvas);

}

class Line extends Primitive {

     private x_1, y_1, x_2, x_2;

     draw(canvas) {

          canvas.drawLine(x_1, y_1, x_2, y_2);

     }

}

class Rect extends Primitive {

     private x_1, y_1, x_2, y_2, x_3, y_3, x_4, y_4;

     draw(canvas) {

          canvas.drawRect(x_1, y_1, x_2, y_2, x_3, y_3, x_4, y_4);

     }

}

Now you can have drawing code that always draws the correct shape with the correct points. E.g:

primitives = [ new Line(), new Line(), new Rect() ];

for (primitive in primitives) { primitive.draw() };

This would not work that easily if you'd use static methods because you'd have to check from which class the static method has to be called, e.g.:

class Primitive {}

class Line extends Primitive {

     private x_1, y_1, x_2, x_2;


     static draw(line, canvas) {

          canvasdrawLine(line.x_1, line.y_1, line.x_2, line.y_2);

     }

}

class Rect extends Primitive {

     private x_1, y_1, x_2, y_2, x_3, y_3, x_4, y_4;

     static draw(rect, canvas) {

          canvas.drawRect(rect.x_1, rect.y_1, rect.x_2, rect.y_2, rect.x_3, rect.y_3, rect.x_4, rect.y_4);

     }

}

Your drawing code will now have to do sth. like this:

primitives = [ new Line(), new Line(), new Rect() ];

for (primitive in primitives) {

     if (typeof(Primitive) == Line) { Line.draw(canvas, primitive) }

     else if (typeof(Primitive) == Rect) { Rect.draw(canvas, primitive) }

};


So as you can see, the objects do not automatically select the right method to draw anymore, that's your job now. Therefore the solutions are not equivalent.


But keep in mind that inheritance is not the only way to solve the problem. Pick the one best suited for the job. You should also look at composition which is considered to be more flexible than inheritance by many.


The first example could as easily implemented by using an interface, but consider that there could be methods that are useful for all primitives, e.g. a transformation.


In this case you could do sth. like this:


abstract class Primitive {

     protected points;


     translate(x, y) {

          for point in Points {

               point.x = point.x + x;

               point.y = point.y + y;

          }

     }


     abstract draw(canvas)

}


By extending the class above all your primitives will have a translate method that will move all points by the given x and y amount.


Best regards,


Frank


More info on Inheritance vs. Composition

language agnostic - Prefer composition over inheritance? - Stack Overflow

https://www.thoughtworks.com/insights/blog/composition-vs-inheritance-how-choose

Added links.

0 Kudos

Hi, Please find my scenario below.

Sandra_Rossi
Active Contributor
0 Kudos

If you have a superclass with 10 methods "concrete" and 15 methods abstract, and you have subclasses where you only implement these abstract methods and need not reimplementing the 10 concrete methods, would you really instead prefer not using an abstract class and implementing the same code in all 10 methods of all subclasses? I prefer doing the code once.

0 Kudos

Hi,

Please find my response and scenario below, I was unable to tag your names correctly.

asuji20
Explorer
0 Kudos

Hello All,

Thank you so much, the below try out was what actually made me doubt why and when do we really need abstract class ( programming wise, not conceptual )

A scenario

abstract_class

method display importing info FINAL   "common method

abstract method "get info"                     "method for redefinition

"if we add new abstract method we need to redefine in all classes - Issue

class1 inheriting from abstract_class

redefine method "get info" to "get name info"

class2 inheriting from abstract_class

redefine method "get info" to "get age info"

class_trigger

class-method call_all importing classimp type ref to abstract_class

call method classimp->get_info()

call method classimp->display()

endmethod

create objects class1, class2

class_trigger->call_all ( class1 ).

class_trigger->call_all ( class2 ).

Now, I can do the same using class-method and normal redefinition

Main_class

class-method display importing info  "common method

method "get info"                               ""method for redefinition

class1 inheriting from main_class

redefine method "get info" to "get name info"

class2 inheriting from main_class

redefine method "get info" to "get age info"

class_trigger

class-method call_all importing classimp type ref to abstract_main

call method classimp->get_info()

call method classimp->display()

endmethod

create objects class1, class2

class_trigger->call_all ( class1 ).

class_trigger->call_all ( class2 ).

i think that's what i am trying to know, why go through the trouble of creating abstract classes methods and compel implementing classes to redefine them all.

@Frank kirck , could you please help me understand this scenario and why abstract is needed

Former Member
0 Kudos

Hi Madhu,

in your example, both approaches will work just fine.

But...

Abstract classes vs. non abstract base classes

Abstract classes are tools to make coding easier by making it easier to communicate the intent of your code to your fellow programmer.

In your example, if I only look at the code you have, I could try to create an instance of the class Main_class which could work or not depending on the implementation. But if you make the class abstract, I know that the Main_class is not intended to be used directly. This will prevent me from making a mistake.

Abstract classes vs. interfaces

You can achieve that I never try to create an instance of Main_class by making it an interface. But now you force me to implement all methods of Main_class anytime I want to create a new class to be used by the static method. If it is possible to provide meaningful default implementation for some of the methods, it makes sense to provide an abstract base class that implements all these method for me so that I can create a new class with less effort.

Best regards,

Frank

0 Kudos

Hello Frank,

Thank you very much. I think i get the point now.

matt
Active Contributor
0 Kudos

Frank Krick wrote:

Abstract classes vs. non abstract base classes

Abstract classes are tools to make coding easier by making it easier to communicate the intent of your code to your fellow programmer.

Not just your fellow programmer, but yourself in a few years time! But it's not just to make things easier - it can be part of good design.

I use interfaces for polymorphism mainly, where subclassing hierarchies don't make sense.

If you really want to understand how to use abstract classes, sub classes and interfaces well, I suggest that you get hold of a book of Design Patterns, or research into them.

Note, this is not an ABAP specific issue. It pertains across all OO languages.There are some blogs here that talk about ABAP implementations of design patterns. I suggest searching,

Former Member
0 Kudos

Agreed, the gang of four is everywhere

0 Kudos

Thanks Mathew, I sure will when I get a chance.