在C#中使用“抽象覆盖”是什么?

出于好奇,我试图覆盖基类中的抽象方法,并且实现抽象方法。 如下:

public abstract class FirstAbstract { public abstract void SomeMethod(); } public abstract class SecondAbstract : FirstAbstract { public abstract override void SomeMethod(); //?? what sense does this make? no implementaion would anyway force the derived classes to implement abstract method? } 

很想知道为什么C#编译器允许编写“抽象覆盖”。 这不是多余的吗? 应该是编译时错误做这样的事情。 它是否适用于某些用例?

感谢您的关注。

在MSDN上有一个有用的例子 – 基本上你可以强制派生类为方法提供一个新的实现。

 public class D { public virtual void DoWork(int i) { // Original implementation. } } public abstract class E : D { public abstract override void DoWork(int i); } public class F : E { public override void DoWork(int i) { // New implementation. } } 

如果一个虚拟方法被声明为抽象的,那么对于从抽象类inheritance的任何类都是虚拟的。 inheritance抽象方法的类不能访问方法的原始实现 – 在前面的例子中,类F上的DoWork不能调用类D上的DoWork。 通过这种方式,抽象类可以强制派生类为虚拟方法提供新的方法实现

我发现确保派生类中正确的ToString()实现非常有用。 假设您有抽象基类,并且您确实希望所有派生类都定义有意义的ToString()实现,因为您正在使用它。 你可以用abstract override非常优雅的做到这一点:

 public abstract class Base { public abstract override string ToString(); } 

这对于实现者来说是一个明确的信号, ToString()将以某种方式在基类中使用(比如将输出写入用户)。 通常情况下,他们不会考虑定义这个覆盖。

有趣的是,C#编译器的Roslyn版本在其中有一个抽象的重写方法,我发现它足够奇怪的写一篇文章:

http://ericlippert.com/2011/02/07/strange-but-legal/

假设SecondAbstract处于三级层次结构的中间,并且希望从其基础FirstAbstract实现一些抽象方法,而将其他方法X从其子ThirdAbstract

在这种情况下, SecondAbstract被迫用abstract来装饰方法X,因为它不想提供一个实现; 同时,由于它不是定义一个新的方法X,而是强制要用override来装饰它,而是要把执行X的责任移到它的子节点。 因此, abstract override

一般来说, abstractoverridebuild模的概念是正交的。 第一个派生类实现一个方法,而第二个派生类认识到一个方法和基类中指定的相同,而不是new

因此:

  • 既不关键字:“简单”的方法
  • abstract :派生类必须实现
  • override :在基类中定义的方法的实现
  • abstract override :派生类必须实现在基类中定义的方法

这是因为在子类中你不能有与基类相同的名字的abstract方法。 override告诉编译器,你正在重写基类的行为。

希望这是你在找什么。

如果您没有在SecondAbstract声明SomeMethodabstract override ,那么编译器会期望该类包含方法的实现。 有了abstract override ,很明显,实现应该在从SecondAbstract派生的类中,而不是在SecondAbstract本身中。

希望这可以帮助…

这种devise模式被称为模板方法模式。

维基百科页面模板方法

一个简单的非软件示例:有一大堆军事单位:坦克,喷气机,士兵,战列舰等等。他们都需要实施一些常用的方法,但是他们会以不同的方式实施:

  • 移动()
  • 攻击()
  • 撤退()
  • rest()

等等…