防止在C#中重写方法

nig*_*457 21 c# sealed c#-4.0

如何防止在派生类中重写方法?

在Java中,我可以通过final在我希望防止被覆盖的方法上使用修饰符来实现此目的.

我如何在C#中实现同样的目标?
我知道使用sealed但显然我只能用override关键字吗?

class A
{
    public void methodA()
    {
        // Code.
    }

    public virtual void methodB()
    {
        // Code.
    }
}

class B : A
{
    sealed override public void methodB()
    {
        // Code.
    } 
}
Run Code Online (Sandbox Code Playgroud)

所以在上面的例子中,我可以防止methodB()被派生自类的任何类重写B,但是如何防止类首先B覆盖methodB()

更新:当我发布此问题时,我错过了A类声明中的virtual关键字methodB().纠正了它.

Ken*_*rey 28

你不需要做任何事情.所述virtual修饰符指定了一个方法可以被覆盖.省略它意味着该方法是"最终的".

具体来说,方法必须是virtual,abstract或者override被覆盖.

使用new关键字将允许隐藏基类方法,但它仍然不会覆盖它,即当您调用A.methodB()时将获得基类版本,但如果您调用,B.methodB()您将获得新版本.

  • 在一种允许明确拼写出这么多东西的语言中,这是令人沮丧的,没有一个关键字可以明确地说“这并不意味着永远被覆盖”,只要这样你就不会在不考虑的情况下不小心将其变为虚拟的为什么它不是首先的。 (2认同)

Shy*_*yju 20

正如您所提到的,您可以通过使用with来防止进一步覆盖B类中的MethodBsealed override

class B : A
{
    public sealed override void methodB()
    {
        Console.WriteLine("Class C cannot override this method now");
    }
}
Run Code Online (Sandbox Code Playgroud)

使用的sealed改性剂与沿着 override防止派生类进一步重写的方法.

如果您不希望methodBA类被任何子类重写,请不要标记该方法virtual.只需删除它.virtual关键字允许在子类中重写该方法

public void methodA()
{       
}
Run Code Online (Sandbox Code Playgroud)

sealed在类上使用关键字以防止进一步覆盖类

  • @KendallFrey`sealed`可以应用于方法,只要它们也是覆盖.它阻止*进一步*覆盖派生类(如Shyju指出的那样). (8认同)
  • 使用sealed修饰符可以防止类派生自"A类".这不是要求的. (3认同)

Kei*_*thS 5

在C#中,未标记的函数virtual(也包括虚函数的覆盖)实际上是密封的,不能被覆盖.因此,您的示例代码实际上不会编译,因为override关键字无效,除非在基类中有一个标记为virtual且具有相同签名的方法.

如果A.methodB()被标记为虚拟,那么您可以从A覆盖该方法,但是可以防止它在更间接派生的类中被进一步覆盖,使用sealed完全如您所示的关键字.

要记住的一件事是,虽然可以防止方法覆盖,但方法隐藏不能.鉴于您目前对A类的定义,B类的以下定义是合法的,您无能为力:

class B:A
 {
      public new void methodB()
            {
                    //code
            } 
  }
Run Code Online (Sandbox Code Playgroud)

new关键字基本上"打破"继承/覆盖层次结构,因为它与这一方法有关; 任何对B类的引用,被视为B类(或任何进一步派生类型)将使用B类中的实现并忽略A类中的实现,除非B的实现特别回调它.但是,如果要将类B的实例视为类A(通过强制转换或将其作为参数传递),则忽略"新"实现.

这与覆盖不同,其中被视为A类并且真正覆盖虚拟方法B的B类仍将使用B类覆盖该方法.还要了解方法隐藏是推断的(虽然你会得到编译器警告); 如果在派生类中声明具有相同签名的方法并且未指定new或override,则将隐藏基类方法.