当当前类是子类时,为什么在方法或属性上使用sealed

时间:2014-04-12 19:12:18

标签: c#

为什么每当当前类从超类继承时,我们都会在方法或属性上使用sealed关键字?假设我们创建了一个类,并倾向于将一个或多个方法暴露给对象用户,但根本不让它继承,并使用sealed来解决问题。那么,为什么不呢?密封当前继承的类的方法或属性背后的原因是什么?

4 个答案:

答案 0 :(得分:4)

密封课程或方法有两个主要原因。

第一个也是最重要的一个(可能)是你不允许继承有关的类型或方法。在某些情况下这很重要。

第二个原因是编译器可以应用其他方式无法完成的优化。

进行虚拟方法查找不是非常昂贵的事情,但它确实会产生一些开销。如果编译器知道:

  1. 您在特定情况下使用了最具体的课程
  2. 给定类型或方法已密封
  3. 然后在某些情况下,它可以将对方法的调用编译为直接调用正确的方法,而不是通过类型的虚方法表进行查找。这将消除在这种情况下虚拟方法查找的开销

答案 1 :(得分:2)

sealed上的MSDN文档中所述:

  

您还可以在方法或属性上使用sealed修饰符   覆盖基类中的虚方法或属性。这使得   您允许类从您的类派生并阻止它们   覆盖特定的虚拟方法或属性。

换句话说,您可以阻止覆盖在类继承层次结构中进一步发生。作为程序员,您基本上是说这个特定方法应该具有所有子类的通用功能。

这是来自同一篇文章的优秀代码示例:

class X
{
    protected virtual void F() { Console.WriteLine("X.F"); }
    protected virtual void F2() { Console.WriteLine("X.F2"); }
}

class Y : X
{
    sealed protected override void F() { Console.WriteLine("Y.F"); }
    protected override void F2() { Console.WriteLine("Y.F2"); }
}

class Z : Y
{
    // Attempting to override F causes compiler error CS0239. 
    // protected override void F() { Console.WriteLine("C.F"); }

    // Overriding F2 is allowed. 
    protected override void F2() { Console.WriteLine("Z.F2"); }
}

每次请求更新额外澄清

这是sealed方法可能应用的抽象示例。

abstract class Car
{
    public abstract void Make();
}

class Ford : Car
{
    // We don't want someone inheriting from this class to change the
    // 'Make' functionality - so we seal the method from being further
    // overridden down the inheritance hierarchy 
    sealed public override void Make() { Console.WriteLine("Ford"); }
}

// This way there is no way (besides shadowing) someone inheriting from Ford
// can change the behavior of Make() - so these two types will contain the 
// same behavior. Pretty nice, eh!? 
class Focus : Ford
{ 
}

class Escape : Ford
{
}

答案 2 :(得分:1)

正如文档(http://msdn.microsoft.com/en-us/library/88c54tsw.aspx)中所述,这可以防止方法成为虚拟方法。它很有用,因为override关键字意味着虚拟。如果要覆盖方法但停止进一步覆盖,可以在方法定义中添加sealed。

如果班级本身已经封存,则没有理由密封特定的方法,因为无论如何都无法继承班级。

答案 3 :(得分:0)

您将sealed应用于重写的方法(或属性等),以禁止从您的类派生的类,进一步覆盖该方法。