Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 保持子类中抽象方法的可见性_Java_Abstract Class_Visibility - Fatal编程技术网

Java 保持子类中抽象方法的可见性

Java 保持子类中抽象方法的可见性,java,abstract-class,visibility,Java,Abstract Class,Visibility,我有以下抽象类: public abstract class AbstractCreateActionHandler { protected IWorkItem mCurrentWI; public AbstractCreateActionHandler(IWorkItem wi) { this.mCurrentWI = wi; } public final void invoke() { try { if (c

我有以下抽象类:

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
    }*/
}
子类扩展了抽象类:

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()
方法

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

不,这是不可能的

Java语言规范的章节规定:

重写或隐藏方法的访问修饰符(§6.6)必须提供至少与重写或隐藏方法相同的访问,如下所示:

因此,总是可以让重写方法提供比父类中重写方法更多的访问权限


另请参见。

允许将修饰符更改为public,因为它不违反

因此,“正常”调用序列和在 可以绕过抽象类方法invoke()。有办法去吗 检查是否调用了invoke()方法


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

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

好的……我可能已经知道了。所以也无法检查是否调用了invoke()方法,对吗?战略模式看起来不错。将有一个更仔细的观察。@sk2212-好吧,有很多方法可以做到这一点,比如获取当前堆栈跟踪并回顾它,或者维护一个成员变量,比如“inInvoke”,但我不推荐任何一种:)