我相信我希望类的某些方法和属性是不可重写的,并在所有派生类中使用base的实现。怎么做到这一点? sealed关键字似乎不起作用,并说“方法不能被密封,因为它不是覆盖”。
答案 0 :(得分:14)
默认情况下,成员在C#中被密封 - 除非它们被标记为虚拟,否则它们无法在派生类中被覆盖。
在派生类中,它们可以 shadowed ,诚然:
public new void SomeMethod()
{
}
......但这与覆盖不一样。你无法阻止这种情况,但如果调用者使用基类的编译时类型,他们最终不会意外地调用它。
如果您可以向我们提供完全您要阻止的内容的详细信息(来自调用方的POV和被调用的代码),我们可以提供更多帮助。
答案 1 :(得分:5)
除非您将其标记为virtual
,否则不会覆盖的方法不会被覆盖。所以听起来好像不需要采取行动。
class A
{
public void B() {} // can't override
public virtual C() {} // can override
public virtual D() {} // can override
}
sealed
修饰符仅在方法已覆盖基类中的成员时才适用。这允许您防止 类的子类中的覆盖。
class A1 : A
{
public void B() {} // shadows A.B. Not a virtual method!
public override C() {} // overrides A.C, subclasses can override
public override sealed D() {} // overrides A.D, subclasses cannot override
// (but can shadow)
}
答案 2 :(得分:2)
这是不可能的。派生类总是可以使用new关键字来隐藏(而不是覆盖)其父方法。 sealed关键字只是阻止派生类覆盖虚方法,但它仍然可以使用new来隐藏基本方法。
答案 3 :(得分:1)
只有在覆盖虚拟方法但不希望从实现派生的类再次覆盖它时,才能使用“sealed”关键字。您只需要声明方法不是虚拟的。
正如其他人指出的那样,实际上存在一个“new”关键字,它允许隐藏方法。但只要您使用基类的引用,就始终会调用基本方法:
class BaseClass
{
public void Foo() { Console.WriteLine("Foo"); }
}
class Derived : BaseClass
{
public new void Foo() { Console.WriteLine("Bar"); }
}
public static void Main()
{
Derived derived = new Derived();
derived.Foo(); // Prints "Bar"
BaseClass baseClass = derived;
baseClass.Foo(); // Prints "Foo"
}
由于只提供基类是有意义的,只要你到处使用“BaseClass” - 指针,你的方法就无法隐藏。
答案 4 :(得分:0)
这正是sealed
关键字的用途。
http://msdn.microsoft.com/en-us/library/ms173150.aspx
班级成员,方法,领域, 派生类上的属性或事件 这是覆盖虚拟成员的 基类可以声明该成员 密封的。这否定了虚拟 成员方面的任何进一步 派生类。这是通过 把密封的关键字放在之前 在类成员中覆盖关键字 声明。
如果您从基类重写方法而不是使用sealed
。
如果你已经在类中声明了一个方法,并且不希望它在任何派生类中被覆盖,那么不要将其标记为virtual
。只能覆盖virtual
个成员。