为什么每当当前类从超类继承时,我们都会在方法或属性上使用sealed
关键字?假设我们创建了一个类,并倾向于将一个或多个方法暴露给对象用户,但根本不让它继承,并使用sealed
来解决问题。那么,为什么不呢?密封当前继承的类的方法或属性背后的原因是什么?
答案 0 :(得分:4)
密封课程或方法有两个主要原因。
第一个也是最重要的一个(可能)是你不允许继承有关的类型或方法。在某些情况下这很重要。
第二个原因是编译器可以应用其他方式无法完成的优化。
进行虚拟方法查找不是非常昂贵的事情,但它确实会产生一些开销。如果编译器知道:
然后在某些情况下,它可以将对方法的调用编译为直接调用正确的方法,而不是通过类型的虚方法表进行查找。这将消除在这种情况下虚拟方法查找的开销。
答案 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
应用于重写的方法(或属性等),以禁止从您的类派生的类,进一步覆盖该方法。