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

いいえ、それを制限する方法は実際にはありません。悪意のある開発者や無知な同僚が心配ですか? 後者の場合は、「メソッドの可視性を高めない」などのコーディング規則を確立し、適切な使用法を示す javadoc を抽象メソッドに配置する必要があります。前者の場合は、おそらく別の方法でコードを設計する必要があります (おそらく戦略パターンを使用します)。

于 2013-03-28T13:39:39.560 に答える
4

抽象クラスを拡張し、executeAction() メソッドを実装する開発者が、executeAction() の可視性を変更できない可能性はありますか?

いいえ、これは不可能です。

8.4.8.3 章。Java言語仕様のオーバーライドおよび非表示の要件では、次のように指定されています:

オーバーライドまたは非表示のメソッドのアクセス修飾子 (§6.6) は、次のように、少なくともオーバーライドまたは非表示のメソッドと同程度のアクセスを提供する必要があります。 ...

したがって、オーバーライドするメソッドが親クラスのオーバーライドされたメソッドよりも多くのアクセスを提供することは常に可能です。

Java アクセス修飾子とメソッドのオーバーライドも参照してください。

于 2013-03-28T13:38:17.570 に答える
0

Liskov Substitution Principleに違反していないため、modifier を public に変更することは許可されています。

そのため、抽象クラス メソッド invoke() で実行される「通常の」呼び出しシーケンスとチェックをバイパスできます。invoke() メソッドが呼び出されたかどうかを確認する方法はありますか?

誰かに参照を渡すと、クラスで公開されていAbstractCreateActionHandlerないため、呼び出し元はメソッドを見ることができません。したがって、基本クラスへの参照を呼び出し元に渡すと、呼び出し元は実行シーケンスをバイパスできなくなります。Concrete クラスへの参照を渡すと、シーケンスが壊れる可能性があります。executeActionAbstractCreateActionHandler

于 2013-03-28T13:39:07.920 に答える