我有一个混乱我想解决..在C#中,只有virtual
标记的基类方法可以在派生类中被覆盖。不能覆盖没有virtual
标记的基类方法。最好的情况是,派生类可以使用new
隐藏基类方法。然后我们有sealed
个方法,这些方法也不能在基类中重写。
那么,密封方法和标准非虚方法有什么区别?
另一个相关问题。可以使用sealed
?
new
方法
答案 0 :(得分:12)
sealed
可防止进一步覆盖链上的虚拟方法。您只能在覆盖的方法上定义sealed
。请查看sealed
:http://msdn.microsoft.com/en-us/library/aa645769(v=vs.71).aspx
他们给出了密封使用的一个很好的例子:
using System;
class A
{
public virtual void F() {
Console.WriteLine("A.F");
}
public virtual void G() {
Console.WriteLine("A.G");
}
}
class B: A
{
sealed override public void F() {
Console.WriteLine("B.F");
}
override public void G() {
Console.WriteLine("B.G");
}
}
class C: B
{
override public void G() {
Console.WriteLine("C.G");
}
}
在这种情况下,任何源自B
的人都可以覆盖G
,但不能覆盖F
。
答案 1 :(得分:2)
如果我正确阅读this,则密封可以阻止虚拟虚拟。基本上撤消虚拟。
答案 2 :(得分:2)
密封方法只能是覆盖基类方法的方法,因此不能进一步覆盖。
来自文档:
当实例方法声明包含一个密封修饰符时,即 方法据说是一种密封方法 如果是实例方法 声明包括密封修饰符,它还必须包括 覆盖修饰符。
虚拟方法不需要这样做。
答案 3 :(得分:0)
原始海报问了两个不同的问题:
sealed
方法和标准非虚拟方法之间有什么区别?sealed
在派生类中替换基类new
方法吗?sealed
与非虚拟方法之间的区别如果您不希望子类能够访问要添加的新方法,则创建非虚拟方法是理想的解决方案。例如,您可以向不在其父类中的类添加非虚拟方法。
但是,有时您的班级的父类将方法定义为virtual
,但是您不希望班级的任何子级都能够覆盖此方法的特定override
。这是您使用sealed
的时候。它告诉编译器不再可以覆盖一次virtual
方法。请参阅sealed
here上的文档。
sealed
替换基类new
的方法是的,他们可以,尽管这可能无法实现您的想法。替换sealed
方法的确意味着现在调用该方法将调用您的实现。但是,如果您的类曾经转换为对父类的引用,则将使用该方法的父类实现,而不是您的方法。 Microsoft文档对此here进行了说明。
下面的示例与Microsoft的文档略有修改:
public class A
{
public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
public override void DoWork() { Console.WriteLine("B"); }
}
public class C : B
{
public sealed override void DoWork() { Console.WriteLine("C"); }
}
public class D : C
{
// Uncommenting the following line would cause a compilation error, since DoWork is sealed
// public override void DoWork() { Console.WriteLine("D"); }
public new void DoWork() { Console.WriteLine("D"); }
}
...
// Later on in a class
D d = new D();
d.DoWork(); // Prints "D"
C c = d;
c.DoWork(); // Prints "C"