在C#中,如果我们从类继承,它允许我们覆盖虚方法。
可以通过在方法中不使用virtual
关键字来防止这种情况,但仍然可以通过使用new
关键字实现该方法来隐藏它。
是否有任何方法可以防止覆盖和阴影,而不会将方法设为私有?
class myBaseClass{
public void method1(){ //Implementation }
}
class myDerivedClass : myBaseClass{
public new void method1() { //new Implementation }
}
答案 0 :(得分:8)
它总是可以被隐藏,但这不是压倒性的 - 它是阴影。理解两者之间的区别非常重要。你不能阻止阴影(虽然允许类本身派生),不。你为什么这么想?你试图阻止什么不良影响?
密封类本身是一个单独的选项:
sealed class MyBaseClass {
...
}
就我个人而言,我喜欢封印任何我不会设计的课程,但这是一个不同的(也是有争议的)问题。
答案 1 :(得分:2)
通过阅读您的问题和您的意见,似乎实际的解决方案可能不在代码中,而在于理解。
当你覆盖一个方法(在你可以覆盖它之前将作为一个虚方法)时,该方法会调用该类型的任何对象,而不考虑编译时类型
有关覆盖和隐藏的区别的说明,请参阅下面的代码
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
请注意, 不 的最后一行使用Derived中定义的方法,但使用基类中的方法,因为它不是虚拟的 compile time类型确定将调用哪个方法, compile 时间类型dAsb
是BaseClass。因此,即使d
和dAsb
完全相同,也会调用两个不同的方法,因为编译时类型不同。
无论隐藏非虚拟方法的人是谁,任何用BaseClass编写的代码都将按预期工作。
答案 2 :(得分:1)
标记方法sealed
:
public sealed void method1()
{
//Implementation
}
当然,你不能完全阻止它。然而,我可能误解了你的问题,因为看起来你可能想要防止阴影,就像Jon Skeet所说的那样。没有办法阻止它。