2015-03-19 117 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

考虑你定义在类中实现的方法,在你的程序,你只需要这个实现。例如,您向用户返回一条消息,只要您调用此方法,您希望返回特定的消息,则认为您有一个覆盖该方法并显示另一条消息的子类,当您调用该方法时,会得到另一个不是预期的结果,如果您将某个类标记为密封,则可以防止意外继承。 密封是从抽象的设计硬币的正面。当你定义一个抽象类时,你允许类从它派生出来并为方法实现它们自己的实现,但是密封类不允许其他人根据它来派生它。