抽象方法的部分实现?

6
例如,我有很多类都需要一个特定的方法。 在这个方法中,所有这些类都需要一行代码,而方法的其余部分是不同的。
我该如何实现这样的功能?
void method(){
    everybodyDoesThisStuff;

    // more individual stuff 

    // more individual stuff
}

抽象方法不能有实现体,如果你不将其定义为抽象方法,那么你就会重写该方法并且失去它。


除了将“pull out everybodyDoesThisStuff”放入一个方法中,并从每个method()的覆盖者中显式调用它之外,没有任何真正好的方法来做到这一点。 - Louis Wasserman
individualStuff()moreIndividualStuff()方法声明为抽象方法,并从method()中调用它们。 - aioobe
@LouisWasserman 是的,那是我目前正在做的事情,我只是想知道是否可能像上面那样做。这样我就不必在100个不同的类中调用该方法了。 - 2ARSJcdocuyVu7LfjUnB
1
你可以覆盖它,但仍然可以使用super.method()从派生类中的父类访问该方法。 - Vucko
1
@MitchWeaver 真的吗?确定吗?如果你忘记调用super怎么办?在回答中有更好的方法 - Andy Turner
显示剩余4条评论
4个回答

18

你应该把做“更多个性化的事情”的方法设为抽象方法,而不是整个方法本身。

// AbstractBase.java
public abstract class AbstractBase {
    public final void method() {
        everybodyDoesThisStuff();
        doIndividualStuff();
    }

    abstract void doIndividualStuff();

    private void everybodyDoesThisStuff() {
        // stuff that everybody does
    }
}

// ConcreteClass.java
public class ConcreteClass extends AbstractBase {
    void doIndividualStuff() {
         // do my individual stuff
    }
}

4
如果每次调用method都需要确保执行everybodyDoesThisStuff(),甚至可以将method声明为final - aioobe
2
这被称为模板方法模式 - Andreas

5

一种解决方案是要求所有子类调用super.method()。问题在于没有办法实际强制执行这一点。另一个选项是创建一个单独的方法,在内部执行所需的行并调用抽象方法:

public final void method() {
    callEveryTime();
    doMethod();
}

protected abstract void doMethod();

请注意,method()public final的,因此可以在任何地方调用但不能被覆盖,而doMethod()protected的,因此可以被覆盖但不能在其包外(或子类)调用。

1
这被称为模板方法模式 - Andreas

3

您可以将普通方法调用转换为抽象方法:

void foo(){
    // do stuff
    bar(); // let the abstract method do the rest
}
abstract void bar();

0
如果你在思考是否需要抽象方法的部分实现,那么通常是时候重新考虑你的设计粒度了。
为什么不将 `everybodyDoesThisStuff` 提取到一个单独的方法中,并将其放入一个接口中呢?

你能发布一个例子吗? - shmosel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接