2014-04-09 64 views
1

我發現了幾個問題來解釋覆蓋和隱藏方法的虛擬/覆蓋/新關鍵字,但他們似乎沒有解決我的情況。我有我的MVC控制器,看起來像這樣做驗證碼:繼承和重寫的私人幫手方法

public class AController : BaseController 
{ 
    private bool validate() 
    { 
     //code for A validation 

     return base.validate(); 
    } 
} 

public class BController : BaseController 
{ 
    private bool validate() 
    { 
     //code for B validation 

     return base.validate(); 
    } 
} 

public class BaseController : Controller 
{ 
    protected bool validate() 
    { 
     //code for common validation 
     return isValid; 
    } 
} 

A和B都調用this.validate()在他們的創建和編輯POST方法。據我所知,這工作正常,但我不明白何時/如果我應該使用虛擬/覆蓋。受保護的基礎方法應該是虛擬的嗎?它會改變什麼嗎?我沒有看到編譯器警告我隱藏了繼承的成員,在其他時候我沒有看到「覆蓋」。我猜虛擬/覆蓋不起作用,因爲validate()是一個私有方法。我知道我也可以將BaseController.validate()重命名爲其他內容,例如BaseValidate(),而不必考慮重寫。這一點是否重要,或者這種方法被稱爲「驗證」還是一個不同的名稱?

回答

0

您可以製作BaseController摘要。

然後創建一個所有後代類型必須實現的抽象屬性。

所以,你比如將成爲:

public class AController : BaseController 
{ 
    protected override bool abstractValidation() 
    { 
     //code for A validation 
    } 
} 

public class BController : BaseController 
{ 
    protected override bool abstractValidation() 
    { 
     //code for B validation 
    } 
} 

public abstract class BaseController 
{ 
    protected abstract bool abstractValidation(); 

    protected bool validate() 
    { 
     //code for common validation 

     //then, call the implementations validation method 
     var isValid = abstractValidation(); 

     return isValid; 
    } 
} 
1

與您的代碼,如果BaseController一些方法要驗證控制器,它不能。它可以調用validate,但由於它是一個非虛方法,它只會執行基類的有效性定義。您可能希望它使用實際派生類型的有效性定義,而不是省略其他檢查。

由於方法爲private,所以沒有編譯器警告,因爲您猜對了,因爲該方法是private。一個private方法不可能覆蓋該方法;他們永遠不會是虛擬的。它必須始終隱藏同一方法的任何繼承定義。

1

我應該使用virtual/override

我假設派生控制器中的其他方法調用validate()。在這種情況下,它看起來不像你需要它。

如果您想以另一種方式構建驗證邏輯,並且基類調用子類中的可選附加驗證程序,那麼您可能會從重寫中受益。

public class AController : BaseController 
{ 
    protected override bool additionalValidate() 
    { 
     //code for A validation 

     return isValid; 
    } 
} 

public class BController : BaseController 
{ 
    protected override bool additionalValidate() 
    { 
     //code for B validation 

     return isValid; 
    } 
} 

public class BaseController : Controller 
{ 
    virtual bool additionalValidate() { 
     return true; 
    } 
    protected bool validate() 
    { 
     //code for common validation 
     return isValid && additionalValidate(); 
    } 
} 

這種模式被稱爲Template Method。它比你的實現更脆弱,因爲子類不能「忘記」調用基類驗證。

我沒有看到關於「隱藏繼承成員」的編譯器警告,我在其他時候看到過,當我不使用「覆蓋」時。

你是對的 - 那是因爲子類中的bool validate()方法是private