3

我面临以下问题:

我定义了一个抽象类,其中包含必须由子类实现的公共生成、克隆等方法。但是我想确保当这些公共方法被调用时,某些其他方法也会在抽象类中执行。

一个明显的解决方案是实现一个受保护的抽象方法和一个公共的非抽象方法,该方法调用抽象方法和我需要的所有其他方法。

例如:

abstract class Representation {

    public void generate(int variable) {
        myFunction();
        generateAbstract(variable);
    }

    protected abstract void generateAbstract(int variable);

    private void myFunction() {
        //do something
    }
}

我的问题是如何以更好的方式解决它,或者如果这是以用户友好的方式命名函数的方法。

谢谢!

4

6 回答 6

5

你解决这个问题的方法非常标准,甚至有一个名字:它叫做模板方法模式。这个想法是提供一个公共方法来执行您的算法的高级步骤,并使用子类中受保护的抽象方法的覆盖来处理算法的较低级别的步骤。这是解决问题的正确方法。

于 2012-07-31T13:22:01.773 回答
3

我会像你那样做。我也会制作包装方法

  1. final所以我不能在一个子类中被吹走,或者
  2. 记录方法的地狱,表明必须调用抽象方法......
于 2012-07-31T13:21:29.987 回答
1

@dasblinkenlight 的答案确定了解决您的问题的设计模式:模板方法。我更喜欢这个模板方法链接,而不是回答引用的维基百科条目。另外,我喜欢代码示例的答案:

// Demonstrate the template method design pattern
// straight out of GoF example
abstract class AbstractClass {
    // Final ensures extender does not override, but depends on your design
    final void templateMethod() {
        primitiveOperation1();
        primitiveOperation2();
    }

    // document extenders should keep as protected
    // so clients do not call directly
    protected abstract void primitiveOperation1();
    protected abstract void primitiveOperation2();
}

public class ConcreteClass extends AbstractClass {
    @Override
    protected void primitiveOperation1() {
        System.out.println("ConcreteClass.primitiveOperation1()");
    }

    @Override
    protected void primitiveOperation2() {
        System.out.println("ConcreteClass.primitiveOperation2()");
    }
}
于 2012-07-31T13:48:59.440 回答
0

我认为您建议的方法足够优雅。我以前肯定以这种方式解决过同样的问题。我可能会调用你的方法doGenerate()(或者没有这个词Abstract的东西)。

于 2012-07-31T13:20:58.130 回答
0

我认为最简单的方法是确保super.generate调用它。由于 Java 没有一个很好的机制来通知一个类什么时候被子类化(其他像 Ruby 一样),所以你不能做太多事情来强制实现抽象方法的子类调用另一个方法。

于 2012-07-31T13:24:40.977 回答
0

如前所述,您建议的是根据模板方法模式的正确方法。剩下的就是命名问题。我不会调用要覆盖的函数“generateAbstract”,因为当它被实现时,它不再是抽象的了。我推荐类似“makeGenerate()”的东西,它反映了原始功能并暗示了它的作用。

abstract class Representation {

  public void generate(int variable) {
    myFunction();
    makeGenerate(variable);
  }

  protected abstract void generateAbstract(int variable);

  private void myFunction() {
    //do something
  }
}

public class ConcreteClass extends Representation {
  @Override
  protected void makeGenerate() {
    ...
  }
于 2012-07-31T14:07:26.603 回答