2013-03-28 41 views
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()方法的顯影劑是不允許的變化的的公開程度?

目前開發人員可以簡單地將該方法的可見性更改爲「公開」,創建該子類的對象並調用executeExtion()。可見性修改器可以改變,抽象方法仍然被接受爲「已實施」。

所以其在抽象類方法invoke()執行「正常」的調用順序和檢查可以被旁路。有沒有辦法檢查invoke()方法是否被調用?

回答

3

沒有,有沒有真正以限制的方式。你是否擔心惡意開發者或無知的同事?如果是後者,那麼你只需要建立像「不增加方法可見性」這樣的編碼約定,並在抽象方法上加上一些javadoc來指示正確的用法。如果是前者,那麼你可能需要設計不同的代碼(可能使用戰略模式)。

+1

好的...我可能已經知道它。所以也沒有辦法檢查是否調用了invoke()方法,對吧?戰略模式看起來不錯。仔細看看。 – sk2212

+0

@ sk2212 - 好吧,有一些令人髮指的方法可以像獲取當前堆棧跟蹤並回顧它,或者維護像「inInvoke」這樣的成員變量,但我不會推薦這些:) – jtahlborn

4

是否有可能擴展抽象類並實現executeAction()方法的開發人員不允許更改executeAction()的可見性?

不,這是不可能的。

Java語言規範的章節8.4.8.3. Requirements in Overriding and Hiding指定:

接入改性劑(6.6節)壓倒一切的或隱藏方法必須提供至少儘可能多訪問作爲被覆蓋的或隱藏的方法,如下所示:。 ..

因此總是可能有壓倒一切的方法提供了比在父類中重寫的方法訪問。

java access modifiers and overriding methods見。

0

它允許在修改變更爲公開,因爲這並不違反Liskov Substitution Principle

因此,可以繞過抽象類方法invoke()中執行的「正常」調用序列和檢查,它們在 中執行。有沒有一種方法來檢查 如果invoke()方法被調用?

如果你通過一個人的參考AbstractCreateActionHandler那麼調用者將無法看到該方法executeAction,因爲它是AbstractCreateActionHandler類公共。因此,主叫方將無法繞過執行順序,如果你通過參照基類的調用者。如果你傳遞給具體類的引用,那麼序列可以被破壞。