Zee*_*han 5 c# oop overriding virtual-functions sealed
关于方法重写和OOP原则的有效性,我有一点混乱.我知道关于密封,阴影,覆盖,虚拟等的一切,但我遇到了一个场景,这让我很困惑.假设我有:
class classA
{
public virtual void sayhello()
{
Console.WriteLine("hello I'm A");
}
};
class classB :classA
{
public override void sayhello()
{
Console.WriteLine("hello I'm B");
}
};
class Program
{
static void Main(string[] args)
{
classB a = new classB();
a.sayhello();
}
}
Run Code Online (Sandbox Code Playgroud)
根据我到目前为止研究的所有内容,可以使用子类中的override关键字覆盖声明为virtual或abstract(在抽象类中)的方法.根据这个,上面的代码工作完美.当我删除virtual关键字,然后尝试使用override关键字覆盖该方法时,编译器会给出错误:
不能覆盖继承的成员'inheritence.classA.sayhello()',因为它没有标记为虚拟,抽象或覆盖
然后我从子类中删除了覆盖关键字,并将实现提供为:
class classB :classA
{
public void sayhello()
{
Console.WriteLine("hello I'm B");
}
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,该方法可以被覆盖.我能够覆盖不是虚拟或抽象的方法.所以,我的问题是:
1.它是否违反了OOP原则?因为我能够覆盖在父级中未标记为虚拟的方法.
2.为什么我允许以这种方式覆盖方法?哪个甚至没有标记虚拟?
3.从classA方法中删除虚拟关键字,当我尝试在classB中覆盖该方法时,它给了我classA中密封方法的感觉.(正如我之前提到的编译器错误).如果我删除虚拟,以便子类可能不会覆盖它,那么为什么子类可以巧妙地覆盖它,删除它的override关键字?这仅仅是这种情况,密封关键字是专为?
我想告诉您,您隐藏了未覆盖的父子方法。
您可能没有注意到做同样的事情的另一件事是看到警告,因为在警告部分将明确提到,
警告“行号”
'classB .sayhello'隐藏了继承的成员'classA.sayhello'。如果打算隐藏,请使用 new 关键字。
你的问题,
这不是违背了OOP原则吗?因为我能够重写该方法,该方法在父级中未标记为虚拟。
不,它肯定没有违反 OOP 原则,因为您隐藏了基类方法。
为什么我可以以这种方式重写该方法?哪个甚至没有标记为虚拟?
因为C#不仅支持重写,还支持方法隐藏,并且隐藏方法必须使用new关键字声明。有关更多信息,请阅读dotnet_polymorphism和override-vs-method-hiding
密封关键字是专为这种情况设计的吗?
从MSDN 来看,sealed sealed关键字旨在防止类的派生并否定虚拟成员的虚拟方面。
method-hiding。阅读不可重写方法以获取更多信息