确保方法被调用

4

我有这个类:

public abstract class AbstractIncomingCall {

    /*
    class properties
    */

    public void changeStatus(/*some parameters*/){
        //store parameters in class properties
        isValid();
    }

    protected abstract boolean isValid();
}

...这个类扩展了它:

public class IncomingCallImpl extends AbstractIncomingCall{

    //I override the parent's method
    public void changeStatus(/*same parameters as parent's method*/) {
        super.changeStatus(/*same parameters as parent's method*/);
        //do something interesting 
    }

    protected boolean isValid() throws StatusChangeNotOccurredException {
        //implement my validation algorithm
    }

我希望实现的目标是,每当调用changeStatus(/*一些参数*/)时,都会调用isValid()方法;请注意,isValid()方法仅在具体类中实现,并且它使用从父类继承的类属性。 除了调用super之外,我是否有其他方法来确保isValid()被调用? 我非常不喜欢到处传递参数的事实,我认为我正在完全错误的方向上前进,有更清晰的方法来实现这一点。 我想在抽象类中保留“isValid()调用逻辑”,因为每个调用都需要验证,我不能依靠将来记住这一点:P

提前感谢:]

4个回答

15

看起来你想让changeStatus()遵循模板方法模式。在这个模式中,你在抽象类中定义changeStatus()(如果你不信任人们能够正确扩展它,可以将其定义为final),并让它调用所需的方法:

public final void changeStatus()
{
    doSomethingSubclassSpecific();
    isValid()
}


protected abstract doSomethingSubclassSpecific();

差点发了同样的内容...这是一个非常普遍的模式。 - Varkhan
该方法必须始终是final的(不仅仅是因为不信任人们能够正确地扩展)。模板方法模式暗示该方法是final的,这是保证调用序列的唯一方式... - pgras
“确保的唯一方法”听起来很像不信任扩展程序:-) 但是,我同意您的观点,这是正确的实现。 - kdgregory
永远不要相信扩展程序 - 不是因为它们愚蠢,而是因为它们无法读取你的思维。 - DJClayworth
编译器是否可以警告某些方法从未被调用? - lowatt

2
您可以将changeStatus设为final,并在其中添加调用customChangeStatus方法,以便进行重写。示例代码如下: public abstract class AbstractIncomingCall {
/*
class properties
*/

public final void changeStatus(/*some parameters*/){
    //store parameters in class properties
    isValid();
    customChangeStatus();
}

protected abstract void customChangeStatus();
protected abstract boolean isValid();

你甚至可以为customChangeStatus实现一个空方法,这样你就不需要总是实现它。 在changeStatus中使用final关键字,确保在调用类时使用该逻辑。同时,你仍然可以添加自定义行为。


2

您不需要覆盖changeStatus()方法。您非常接近实现模板方法设计模式。


0

我建议使用组合而不是继承。这样事情就会变得更加明显。


你能更明确地表达你的意思吗? - Alberto Zaccagni

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