抽象class和通用代码
abstract class and common code
我对抽象 classes 及其真正用途有疑问。
考虑以下场景:
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;
}
}
所以,我有一个接口 A,它声明了一个方法 execute() 和 2 个实现,AOne 和 ATwo 都是 implement/define execute()
您会注意到两种实现中的执行方法都有一些共同的功能,即方法调用 getX() 和 getY()。两种实现中的这些方法做同样的事情,即它们在两个 subclasses.
中都是重复的
现在,进入正题。我将通过在接口和实现之间实现抽象 class 来对上述代码进行一些修改。
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
}
}
您现在会注意到,先前在实现中重复的方法 classes AOne 和 ATwo,即 getX() 和 getY() 已移至抽象 class AbstractA。还要注意 AbstractA 实现了 A 但没有提及 execute() 的任何实现。它只包含 AOne 和 ATwo
通用的代码
现在,我认为以上是对抽象 class 的错误使用和不正确的面向对象编程。摘要 classes 不应该用于保存实现 classes 的通用代码,至少不以这种方式。
有人可以阐明这一点,让我知道以上是否正确。如果是,为什么,如果不是,为什么?
编辑: 我相信我弄错了 "common code" 部分。我同意抽象 classes 用于保存各种实现 classes 共有的功能。但是如果我们认为方法 getX() 和 getY() 是 AOne 和 ATwo class 都需要的某种实用程序,将它们拉到抽象 class 仍然是个好主意吗?
问题的底线是:是否应该使用抽象 classes 来保存来自子classes 的通用实用程序代码?
你说
Abstract classes shouldnt be used to hold code common to implementing classes
这是不正确的。这正是他们的目的。
我会说您的 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() 方法中隔离特定于实现的代码。
在实例变量的上下文中有两种可能性我可以从你给定的代码中想到。
1: 如果你的 getX
和 `getY' 方法使用任何实例变量,那么你的代码是完美的,你可以使用 abstract classes这样/.
2: 如果您的 getX
和 `getY' 方法不使用任何实例变量,则将这些方法替换为 static 任何 util classes 中的方法并直接从 util class 使用,例如 MyUtil.getX 和 MyUtil.getY.
我们会考虑使用不同 class 和方法名称的相同场景。
A - 动物
摘要 A - 人类
AOne - 男
ATwo - 女
getX-走
getY - 坐下
如果我们考虑这种情况,让方法在抽象 class Human 中行走和坐着并没有错。走路和坐着是人类的常见行为 class。有些人可能有不同的步行方式。这种场景可以使用装饰器模式来处理。
如果方法 getX 和 getY 不是 AbstractA 的行为,最好创建适当的 class(es) 并将方法移动到 it/them。
我对抽象 classes 及其真正用途有疑问。
考虑以下场景:
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;
}
}
所以,我有一个接口 A,它声明了一个方法 execute() 和 2 个实现,AOne 和 ATwo 都是 implement/define execute() 您会注意到两种实现中的执行方法都有一些共同的功能,即方法调用 getX() 和 getY()。两种实现中的这些方法做同样的事情,即它们在两个 subclasses.
中都是重复的现在,进入正题。我将通过在接口和实现之间实现抽象 class 来对上述代码进行一些修改。
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
}
}
您现在会注意到,先前在实现中重复的方法 classes AOne 和 ATwo,即 getX() 和 getY() 已移至抽象 class AbstractA。还要注意 AbstractA 实现了 A 但没有提及 execute() 的任何实现。它只包含 AOne 和 ATwo
通用的代码现在,我认为以上是对抽象 class 的错误使用和不正确的面向对象编程。摘要 classes 不应该用于保存实现 classes 的通用代码,至少不以这种方式。
有人可以阐明这一点,让我知道以上是否正确。如果是,为什么,如果不是,为什么?
编辑: 我相信我弄错了 "common code" 部分。我同意抽象 classes 用于保存各种实现 classes 共有的功能。但是如果我们认为方法 getX() 和 getY() 是 AOne 和 ATwo class 都需要的某种实用程序,将它们拉到抽象 class 仍然是个好主意吗?
问题的底线是:是否应该使用抽象 classes 来保存来自子classes 的通用实用程序代码?
你说
Abstract classes shouldnt be used to hold code common to implementing classes
这是不正确的。这正是他们的目的。
我会说您的 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() 方法中隔离特定于实现的代码。
在实例变量的上下文中有两种可能性我可以从你给定的代码中想到。
1: 如果你的 getX
和 `getY' 方法使用任何实例变量,那么你的代码是完美的,你可以使用 abstract classes这样/.
2: 如果您的 getX
和 `getY' 方法不使用任何实例变量,则将这些方法替换为 static 任何 util classes 中的方法并直接从 util class 使用,例如 MyUtil.getX 和 MyUtil.getY.
我们会考虑使用不同 class 和方法名称的相同场景。
A - 动物
摘要 A - 人类
AOne - 男
ATwo - 女
getX-走
getY - 坐下
如果我们考虑这种情况,让方法在抽象 class Human 中行走和坐着并没有错。走路和坐着是人类的常见行为 class。有些人可能有不同的步行方式。这种场景可以使用装饰器模式来处理。
如果方法 getX 和 getY 不是 AbstractA 的行为,最好创建适当的 class(es) 并将方法移动到 it/them。