【问题标题】:Overriding methods in C#C#中的重写方法
【发布时间】:2019-07-23 10:27:58
【问题描述】:

学了一个学期的Java,目前正在自学C#。

java(或一般的面向对象编程)的特性之一是能够覆盖继承到子类中的方法。

当我在 C# 中研究此功能时,我试图自己覆盖一个方法,而没有研究在 C# 中覆盖方法的正确方法,它似乎有效。

但是,经过进一步研究,我了解到我们需要在超类中声明方法时使用关键字virtual,而在子类中覆盖方法时需要使用override

所以我的问题是:
在 C# 中覆盖方法的正确方法是什么?

附加说明:我还想知道同样的情况是否适用于 C# 中的重载方法。

【问题讨论】:

  • virtual 关键字的意思是“这是一个可以被覆盖的默认实现”。 abstract 关键字的意思是“必须始终覆盖它”。出于显而易见的原因,如果类也不是 abstract,则不能使用 abstract。正确的方法取决于你需要什么。
  • 我在 Stackoverflow 上找不到直接的问题,我正要回答。
  • @CodeNameJack 那里有are some,他们都没有投票。猜猜大多数问题都会让 cmets 链接到 Microsoft 语言参考。
  • 我建议检查 virual keyword reference 并查看其限制,这将为您提供关于如何/何时覆盖的良好基础。
  • 我会建议override modifier C# Reference - 关于如何覆盖的所有内容都在那里说明

标签: c# .net .net-core methods overriding


【解决方案1】:

根据您是否要提供默认实现,在 .net 中有两种不同的覆盖方式。

  • virtual keyword 确实提供了默认实现。
  • abstract keyword 仅声明必须从继承该类的那些类中重写它的内容。它只能在 abstract 类中使用。

还有其他与继承相关的关键字,例如:

例子:

public abstract class Bank
{
    public abstract string Country { get; } // Everything inheriting must implement it
    public virtual decimal TaxPercent { get { return 0.25; } } // Implementing it is optional
    public decimal DeclareTaxes()
    {
        decimal taxesToPay = 4000 * TaxPercent;
        return taxesToPay;
    }
}

public sealed class BahamasBank: Bank
{
    public override string Country { get { return "Bahamas"; }
    public override TaxPercent { get { return 0.0; } } // Bahamas is different from most countries in tax related stuff
}

public sealed class CanadaBank: Bank
{
    public override string Country { get { return "Canada"; }
}

【讨论】:

    【解决方案2】:

    以下内容来自维基百科(参见 here,C# 部分)。

    “C# 确实支持方法覆盖,但仅在使用修饰符overridevirtualabstract 明确请求时才支持。 *)

    abstract class Animal {
      public          String Name {get; set; }
      // Methods
      public          void   Drink();
      public virtual  void   Eat();
      public          void   Go();
    }
    
    class Cat : Animal {
      public new      String Name {get; set; }
      // Methods
      public          void   Drink();  // warning: hides inherited drink(). Use new
      public override void   Eat();    // overrides inherited eat().
      public new      void   Go();     // hides inherited go().
    }
    

    当用另一种方法覆盖一种方法时,两种方法的签名必须相同(并且具有相同的可见性)。在 C# 中,类方法、索引器、属性和事件都可以被覆盖。”


    *)正如bradbury9正确提到的那样,维基百科页面有错误,所以我稍微改变了答案(添加了上面的粗体文字)

    【讨论】:

    • 那个维基引用是错误的。确实必须显式声明它,但它应该是“和virtualabstract”。事实上,它缺少 abstract 关键字。我建议您编辑 wiki 和您的答案或更改您的 MS 参考链接。
    • @bradbury9 - 感谢您的提示,您是绝对正确的。我更改了答案并添加了脚注。另外,我更新了维基百科的文字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-16
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 2010-12-11
    相关资源
    最近更新 更多