I have a question about abstract classes and their real purpose.
Consider the below scenario:
interface A {
void execute();
}
class AOne implements A {
public void execute() {
x = getX();
..
functionality specific to A
..
y = getY();
..
more funtionality specific to A
}
private X getX() {
..
return x;
}
private Y getY() {
..
return y;
}
}
class ATwo implements A {
public void execute() {
x = getX();
..
functionality specific to B
..
y = getY();
..
more funtionality specific to B
}
private X getX() {
..
return x;
}
private Y getY() {
..
return y;
}
}
So, I have an interface A which declares a method execute() and 2 implementations, AOne and ATwo both of which implement/define execute() You will notice that the execute methods in both implementations have some common functionality i.e. method calls getX() and getY(). These methods in both implementations do the same thing i.e. they are duplicated in both the subclasses.
Now, to the problem. I will make some modifications to the above code by implementing an abstract class in between the interface and the implementations.
interface A {
void execute();
}
public abstract class AbstractA implements A {
protected X getX() {
..
return x;
}
protected Y getY() {
..
return y;
}
}
class AOne extends AbstractA {
public void execute() {
x = getX();
..
functionality specific to A
..
y = getY();
..
more funtionality specific to A
}
}
class ATwo extends AbstractA {
public void execute() {
x = getX();
..
functionality specific to B
..
y = getY();
..
more funtionality specific to B
}
}
You will notice now that the methods earlier duplicated in the implementation classes AOne and ATwo i.e. getX() and getY() have been moved to the abstract class AbstractA. Also notice that AbstractA implements A but does not mention any implementation for execute(). It just holds the code that is common to AOne and ATwo
Now, I think the above is wrong use of an abstract class and incorrect object oriented programming. Abstract classes shouldnt be used to hold code common to implementing classes, atleast not in this manner.
Could someone please shed some light on this and let me know if the above is correct or not. If it is, why and if it is not why?
Edit: I believe I got the "common code" part wrong. I agree that abstract classes are used to hold functionality common to various implementing classes. But if we consider that methods getX() and getY() are some kind of utilities that both AOne and ATwo classes need, is it still a good idea to pull them up to the abstract class?
The bottom line of the question being: should abstract classes be used to hold common utility code from the subclasses?
Because Java only supports single inheritance, a class can implement several interfaces but can extend only one abstract class. An abstract class has at least one abstract method. An abstract method will not have any code in the base class; the code will be added in its derived classes.
An abstract class is a template definition of methods and variables of a class (category of objects) that contains one or more abstracted methods. Abstract classes are used in all object-oriented programming (OOP) languages, including Java (see Java abstract class), C++, C# and VB.NET.
Abstract class: is a restricted class that cannot be used to create objects (to access it, it must be inherited from another class). Abstract method: can only be used in an abstract class, and it does not have a body. The body is provided by the subclass (inherited from).
An abstract class can have constructors like the regular class. And, we can access the constructor of an abstract class from the subclass using the super keyword. For example, abstract class Animal { Animal() { …. } }
You've stated
Abstract classes shouldnt be used to hold code common to implementing classes
which is incorrect. That's precisely what they're for.
I would say that your execute
method could be better designed as part of AbstractA
thus:
public abstract class AbstractA implements A {
protected abstract void doStuff(X x);
protected abstract void doMoreStuff(X x, Y y);
public void execute() {
X x = getX();
doStuff(x);
Y y = getY();
doMoreStuff(x, y);
}
// getX(), getY(), etc...
}
Your implementing classes can then have the implementation-specific code isolated in those abstract doStuff() and doMoreStuff() methods.
We'll think the same scenario with different class and method names.
A - Animal
AbstractA - Human
AOne - Male
ATwo - Female
getX - walk
getY - sit
If we consider this case, there is nothing wrong in having the methods walk and sit in the abstract class Human. Walking and sitting are common behavior for human class. Some people may have different styles of walking. This kind of scenario can be handled using decorator pattern.
If the methods getX and getY are not a behavior of AbstractA, it would be better to create appropriate class(es) and move the mthods to it/them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With