关于覆盖规则C#的混淆

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关键字覆盖声明为virtualabstract(在抽象类中)的方法.根据这个,上面的代码工作完美.当我删除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关键字?这仅仅是这种情况,密封关键字是专为?

dbw*_*dbw 3

我想告诉您,您隐藏了未覆盖的父子方法。
您可能没有注意到做同样的事情的另一件事是看到警告,因为在警告部分将明确提到,

警告“行号”'classB .sayhello'隐藏了继承的成员'classA.sayhello'。如果打算隐藏,请使用 new 关键字。

你的问题,

这不是违背了OOP原则吗?因为我能够重写该方法,该方法在父级中未标记为虚拟。

不,它肯定没有违反 OOP 原则,因为您隐藏了基类方法。

为什么我可以以这种方式重写该方法?哪个甚至没有标记为虚拟?

因为C#不仅支持重写,还支持方法隐藏,并且隐藏方法必须使用new关键字声明。有关更多信息,请阅读dotnet_polymorphismoverride-vs-method-hiding

密封关键字是专为这种情况设计的吗?

MSDN 来看,sealed sealed关键字旨在防止类的派生并否定虚拟成员的虚拟方面。

  • 当应用于类时,sealed 修饰符会阻止其他类继承它。
  • seal 修饰符只能应用于重写基类中的虚拟方法或属性的方法或属性。这可以防止进一步重写特定的虚拟方法或属性,但它永远不会停止method-hiding。阅读不可重写方法以获取更多信息