抽象类和通用代码
我有一个关于抽象类和他们真正目的的问题。
考虑以下情况:
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;
}
}
所以,我有一个声明方法execute()和2个实现的接口A,AOne和ATwo两者都实现/定义execute()你会注意到两个实现中的execute方法都有一些共同的功能,比如方法调用getX()和getY()。 这两种实现中的这些方法都做同样的事情,即它们在两个子类中都是重复的。
现在,解决问题。 我将通过在接口和实现之间实现一个抽象类来对上述代码进行一些修改。
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
}
}
现在您会注意到早期在实现类AOne和ATwo中重复的方法,即getX()和getY()已被移至AbstractA类。 另请注意,AbstractA实现了A,但没有提及execute()的任何实现。 它只是拥有AOne和ATwo共同的代码
现在,我认为以上是错误地使用抽象类和不正确的面向对象编程。 抽象类不应该被用来保存实现类的通用代码,至少不是这种方式。
有人可以请说明这一点,让我知道如果以上是正确的。 如果是这样,为什么,如果不是原因?
编辑:我相信我得到了“通用代码”部分错误。 我同意抽象类用于保存各种实现类的通用功能。 但是如果我们认为方法getX()和getY()是AOne和ATwo类需要的某种实用工具,将它们提升到抽象类还是一个好主意吗?
问题的底线是: 是否应该使用抽象类来保存子类中的常用实用程序代码?
你已经说过
不应该使用抽象类来保存实现类的通用代码
这是不正确的。 这正是他们的目标。
我会说你的execute
方法可以更好地设计为AbstractA
一部分,因此:
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...
}
然后,您的实现类可以将特定于实现的代码分离到抽象的doStuff()和doMoreStuff()方法中。
我们会用不同的类和方法名称来思考相同的场景。
A - 动物
摘要A - 人
奥恩 - 男
ATwo - 女性
getX - 走
getY - 坐
如果我们考虑这种情况,那么让这些方法走在抽象类Human中就没有错。 走路和坐着是人类的常见行为。 有些人可能有不同的行走方式。 这种场景可以使用装饰器模式来处理。
如果方法getX和getY不是AbstractA的行为,则最好创建适当的类并将方法移动到它/它们。
实例变量的上下文中有两种可能性,我可以从给定的代码片段中思考。
1:如果你的getX
和getY方法使用任何实例变量,那么你的代码是完美的,你可以用这种方式使用抽象类。
2:如果getX
和getY方法不使用任何实例变量,则将这些方法替换为任何util类中的静态方法,并直接从util类使用,如MyUtil.getX和MyUtil.getY 。