2011-11-05 86 views
0

在C#中,如果我们从类继承,它允许我们覆盖虚拟方法。如何防止在C#中覆盖?

这可以通过在方法中不使用virtual关键字来防止,但仍然可以通过使用new关键字实现方法来隐藏。

有没有办法防止覆盖和阴影,而不使其私有方法?

class myBaseClass{ 
    public void method1(){ //Implementation } 
} 

class myDerivedClass : myBaseClass{ 
    public new void method1() { //new Implementation } 
} 

回答

8

它总是可以隐藏的,但这并不是最重要的 - 它是阴影。了解两者之间的差异很重要。虽然你不能阻止阴影(虽然允许类自身派生),但是不能。你为什么想要?你试图防止什么不良影响?

密封类本身是虽然一个单独的选项:

sealed class MyBaseClass { 
    ... 
} 

个人而言,我想封我不设计从得到的任何类,但是这是一个不同的(有争议的)事。

+0

@ZaheerAhmed:这个*不是*覆盖,正如我所说的。它是阴影,你无法阻止它。阴影方法虽然不会被称为多态。 –

+1

@ZaheerAhmed:如果你明白这不是阴影,请停止叫它重写......并且你没有声明你*有*完全防止阴影 - 你说过你*想要*。如果你有*,你应该立即放弃,或选择不同的语言。 –

1

标记方法sealed

public sealed void method1() 
{ 
    //Implementation 
} 

当然,你不能完全阻止它。不过,我可能误解了你的问题,因为你似乎想要防止阴影,正如Jon Skeet所说的那样。没有办法阻止。

+0

这是方法,而不是类 - 并且非覆盖方法默认是封闭的。这就是为什么OP必须在派生类中使用'new'。 –

+0

@Jon Skeet:固定。 – doctorless

+0

密封类不能被继承,但我必须允许类的继承,并且直到它从基类覆盖时才能密封方法:'sealed override void method1(){// Implementation}' –

2

从阅读你的问题和你的意见看来,实际的解决方案可能不是在代码中,而是在理解。

当覆盖方法(其具有是一个虚拟方法,然后才能将其覆盖),该方法是呼吁编译时间类型

的该类型regardsless的任何对象有关的说明在覆盖和隐藏差见下文

public class BaseClass { 

    public virtual void MyVirtual(){ 
     Console.writeLine("Base virtual"); 
    } 

    public void MyNonVirtual(){ 
     Console.WriteLine("Base non virtual"); 
    } 
} 

public class Derived : BaseClass { 

    public virtual void MyVirtual(){ 
     Console.writeLine("Derived virtual"); 
    } 

    public new void MyNonVirtual(){ 
     Console.WriteLine("Derived non virtual"); 
    } 
} 

BaseClass b = new BaseClass(); 
Derived d = new Derived(); 
BaseClass dAsb = d; 

b.MyVirtual(); //prints Base virtual 
b.MyNonVirtual(); //print Base non virtual 

d.MyVirtual(); //prints Derived virtual 
d.MyNonVirtual(); //print Derived non virtual 

dAsb.MyVirtual(); //prints Derived virtual 
dAsb.MyNonVirtual(); //print Base non virtual 

通知的代码,最后一行将使用,但从基类b在派生所定义的方法,所述方法因为它不是虚拟的编译时间类型决定哪个方法将被调用并且编译时间类型dAsb是BaseClass。因此即使ddAsb是完全相同的对象,因为编译时间类型不同,所以会调用两个不同的方法。 无论有人隐藏非虚拟方法,任何使用BaseClass编写的代码都会按预期工作。