抽象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.getXMyUtil.getY.

我们会考虑使用不同 class 和方法名称的相同场景。

A - 动物

摘要 A - 人类

AOne - 男

ATwo - 女

getX-走

getY - 坐下

如果我们考虑这种情况,让方法在抽象 class Human 中行走和坐着并没有错。走路和坐着是人类的常见行为 class。有些人可能有不同的步行方式。这种场景可以使用装饰器模式来处理。

如果方法 getX 和 getY 不是 AbstractA 的行为,最好创建适当的 class(es) 并将方法移动到 it/them。