2015-03-19 116 views
2

我有點新的C#,並正在研究有關密封類,當我遇到 來到這個可以派生類腐敗的基類的實現

「密封類主要是通過阻止 意外用於安全原因推導由派生類可能會破壞在基類中提供'

實施這真的可能嗎?派生類可以真正腐敗基類的實現嗎?如果有的話,可以請一個例子來解釋。

+4

這一切都取決於「腐敗」一詞的含義 - 以及基類的設計。但是,舉個例子,如果你有一個類型是不可改變的,但是不是密封的,那麼任何人都可以創建一個從它派生的可變類 - 即使基類中的狀態保持不變,開發人員也無法依靠類本身是不可變的。 – 2015-03-19 10:17:50

回答

1

說你需要一些門衛:

public interface IGateKeeper 
{ 
    /// <summary> 
    /// Check if the given id is allowed to enter. 
    /// </summary> 
    /// <param name="id">id to check.</param> 
    /// <param name="age">age to check</param> 
    /// <returns>A value indicating whether the id is allowed to enter.</returns> 
    bool CanEnter(string id, int age); 

    ... other deep needs ... 
} 

你可能有一個堅實的實施來測試你的酒吧入口處的大多數:

public class MajorityGateKeeper : IGateKeeper 
{ 
    public virtual bool CanEnter(string id, int age) 
    { 
     return age >= 18; 
    } 

    ... other deep implementation ... 
} 

同時還提供了貴賓室的實現:

public class VipGateKeeper : MajorityGateKeeper 
{ 
    public override bool CanEnter(string id, int age) 
    { 
     // Do the majotity test and check if the id is VIP. 
     return base.CanEnter(id, age) && (id == "Chuck Norris"); 
    } 
} 

,並在第二打破它:

public class DrunkGateKeeper : VipGateKeeper 
{ 
    public override bool CanEnter(string id, int age) 
    { 
     return true; 
    } 
} 

的DrunkGateKeeper是VipGateKeeper,所以你可以將其隱藏喝醉了(轉換爲VipGateKeeper) 。但它做了一件糟糕的工作。

var gk = (VipGateKeeper) new DrunkGateKeeper(); 
var canEnter = gk.CanEnter("Miley Cyrus", 16);  // true (sic) 

如果使VipGateKeeper密封您確信它不能醉:類型VipGateKeeper 的目的是一個VipGateKeeper罷了。

+0

OMG,你是關於你的示例嗎? – 2015-03-19 10:39:39

+0

我永遠不會試圖禁止HIM進入。 – Orace 2015-03-19 10:47:17

+0

@Orace所以你試圖說的是,一個標記爲密封的對象不能以任何方式改變,因爲它不能被繼承,所以它阻止了基類中提供的實現的任何改變? – Arun 2015-03-19 11:18:03

0

你可能因爲多態性腐敗的基類的實現。

如果類Avirtual方法,可以重寫(即多態性)和類B覆蓋整個方法,並B不輸出相同的東西,A的實現,那麼,它看起來像B已經改變了A實施的實際行爲。

sealed在類級別級別(f.e. override sealed)旨在避免整個類的繼承和多態性。

您也可能會阻止多態性(繼承仍然是可能的)上的某些成員sealed修改重寫他們在派生類以及將它們標記:

public class A 
{ 
    public virtual void DoStuff() {} 
} 

public class B 
{ 
    public override sealed void DoStuff() {} 
} 
+0

我不知道你只能封印某個會員!謝謝 ! – Orace 2015-03-19 10:42:51

+0

@Orace不客氣! C#有很多「隱藏的寶石」:D – 2015-03-19 10:44:45

0

考慮你定義在類中實現的方法,在你的程序,你只需要這個實現。例如,您向用戶返回一條消息,只要您調用此方法,您希望返回特定的消息,則認爲您有一個覆蓋該方法並顯示另一條消息的子類,當您調用該方法時,會得到另一個不是預期的結果,如果您將某個類標記爲密封,則可以防止意外繼承。 密封是從抽象的設計硬幣的正面。當你定義一個抽象類時,你允許類從它派生出來併爲方法實現它們自己的實現,但是密封類不允許其他人根據它來派生它。