abstract class and common code
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 ie method calls getX() and getY(). These methods in both implementations do the same thing ie 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 ie 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?
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.
There are two possibilities in context of instance variables I can think from your given piece of code.
1: If your getX
and `getY' methods uses any instance variables, then your code is perfect, you can use abstract classes in this way/.
2: If your getX
and `getY' methods do not uses any instance variables, then replace these methods with static methods in any of util classes and use directly from util class, like MyUtil.getX and MyUtil.getY .
上一篇: 如何使用方法等
下一篇: 抽象类和通用代码