6

假设我有一个名为“Parent”的抽象父类,它实现了一个名为“DisplayTitle”的方法。我希望这个方法对于每个继承“Parent”的子类都是相同的——如果子类试图实现自己的“DisplayTitle”方法,我想要一个编译错误。如何在 C# 中完成此操作。我相信 Java,我只是将该方法标记为“最终”,但我似乎无法在 C# 中找到替代方法。我一直在搞乱“密封”和“覆盖”,但我无法得到我正在寻找的行为。

例如,在这段代码中:

using System;

namespace ConsoleApplication1
{
  class Parent
  {
      public void DisplayTitle() { Console.WriteLine("Parent's Title"); }
  }

  class ChildSubclass : Parent
  {
      public void DisplayTitle() { Console.WriteLine("Child's Own Implementation of Title"); 
  }

    static void Main(string[] args)
    {
        ChildSubclass myChild = new ChildSubclass();
        myChild.DisplayTitle();
        Console.ReadLine();
    }
  }
}

我想收到一个编译错误,说“ChildSubClass”不能覆盖“DisplayTitle”。我目前收到警告 - 但似乎这是我应该能够做的事情,而且我不知道标记该方法的正确属性。

4

4 回答 4

11

如何在 C# 中完成此操作。我相信 Java,我只是将该方法标记为“最终”,但我似乎无法在 C# 中找到替代方法。

粗略的等价物sealed在 C# 中,但您通常只需要虚拟方法 - 而且您的DisplayTitle方法不是虚拟的。

重要的是要注意这ChildSubclass 不是压倒一切DisplayTitle的——它是隐藏它。任何仅使用引用的代码Parent都不会最终调用该实现。

请注意,使用原样的代码,您应该会收到一个编译时警告,建议您将new修饰符添加到方法中ChildSubclass

public new void DisplayTitle() { ... }

您不能阻止派生类隐藏现有方法,除了密封类本身以防止完全创建派生类......但是不直接使用派生类型的调用者不会在意。

真正关心的是什么?意外的误用,还是故意的问题?

编辑:请注意,您的示例代码的警告将类似于:

Test.cs(12,19): warning CS0108:
        'ConsoleApplication1.ChildSubclass.DisplayTitle()' hides inherited
        member 'ConsoleApplication1.Parent.DisplayTitle()'. Use the new keyword
        if hiding was intended.

我建议你把警告变成错误,然后就更难忽略它们了 :)

于 2012-10-04T17:32:48.970 回答
2

派生类不能覆盖您的方法,您没有将其声明为virtual。请注意,与 Java 相比,C# 中有很大的不同,Java 中的所有方法都是虚拟的。在 C# 中,您必须显式使用关键字。

派生类可以通过再次使用相同的名称来隐藏您的方法。这可能是您正在谈论的编译警告。使用new关键字会抑制警告。此方法不会以任何方式覆盖您的原始方法,您的基类代码始终调用原始方法,而不是派生类中的方法。

于 2012-10-04T17:32:49.867 回答
1

使用sealed 修饰符来防止子类覆盖您的类、属性或方法。使用密封时什么不起作用?

http://msdn.microsoft.com/en-us/library/88c54tsw.aspx

于 2012-10-04T17:30:06.167 回答
0

我相当确定在 C# 中使用方法修饰符关键字无法实现您想要的。

Sealed 仅在覆盖祖先类中的虚拟方法时适用,从而防止进一步覆盖。

于 2012-10-04T17:39:05.540 回答