4

我有以下抽象类:

public abstract class AbstractCreateActionHandler {

    protected IWorkItem mCurrentWI;

    public AbstractCreateActionHandler(IWorkItem wi) {
      this.mCurrentWI = wi; 
    }

    public final void invoke() {
      try {
          if (checkForLockingFile()) {
            this.executeAction();
            Configuration.deleteInstance();
          }
      } catch (IOException e) {
          Configuration.deleteInstance();
          e.printStackTrace();
      }
    }

    protected abstract void executeAction();    

    private boolean checkForLockingFile() throws IOException {
      String path = Configuration.getInstance().getProperty("path");
      File lock = new File(path + "lock_"+mCurrentWI.getId()+"__.tmp");
      if(!lock.exists()) {
          lock.createNewFile();
          return true;
      }
      return false; 
    }
}

子类扩展抽象类:

public class MyAction extends AbstractCreateActionHandler {

    public MyAction(IWorkItem wi) {
      super(wi);
    }

    @Override
    protected void executeAction() {
      // Implementation
    }

    // ALSO POSSIBLE...
    /* @Override
    public void executeAction() {
      // Implementation
    }*/
}

问题:

扩展抽象类和实现executeAction()方法的开发人员是否可能不允许更改可见性executeAction()

目前,开发人员可以简单地将方法的可见性更改为“public”,创建子类的对象并调用executeExtion()。可见性修饰符可以更改,抽象方法仍被接受为“已实现”。

invoke()因此可以绕过在抽象类方法中执行的“正常”调用顺序和检查。有没有办法检查该invoke()方法是否被调用?

4

3 回答 3

4

扩展抽象类并实现 executeAction() 方法的开发人员是否可能不允许更改 executeAction() 的可见性?

不,这是不可能的。

8.4.8.3 章。Java 语言规范的覆盖和隐藏要求指定:

覆盖或隐藏方法的访问修饰符(第 6.6 节)必须提供至少与覆盖或隐藏方法一样多的访问权限,如下所示: ...

因此,总是有可能让覆盖方法提供比父类中的覆盖方法更多的访问权限。

另请参见java 访问修饰符和覆盖方法

于 2013-03-28T13:38:17.570 回答
4

不,没有真正的方法来限制它。您是否担心恶意开发人员或无知的同事?如果是后者,那么您只需要建立诸如“不要增加方法的可见性”之类的编码约定,并将一些 javadoc 放在抽象方法上,以指示正确使用。如果是前者,那么您可能需要以不同的方式设计代码(可能使用策略模式)。

于 2013-03-28T13:39:39.560 回答
0

允许将修饰符更改为 public ,因为它不违反Liskov 替换原则

因此可以绕过在抽象类方法 invoke() 中执行的“正常”调用序列和检查。有没有办法检查是否调用了 invoke() 方法?

如果您将引用传递给某人,AbstractCreateActionHandler那么调用者将无法看到该方法executeAction,因为它在类中不是公共AbstractCreateActionHandler的。因此,如果您将对基类的引用传递给调用者,调用者将无法绕过执行顺序。如果您传递对 Concrete 类的引用,则可以破坏序列。

于 2013-03-28T13:39:07.920 回答