在C#中使用'抽象覆盖'有什么用?

Man*_*ani 47 c# overriding abstract

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

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?
}
Run Code Online (Sandbox Code Playgroud)

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

谢谢你的关注.

Bro*_*ass 60

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.
    }
}
Run Code Online (Sandbox Code Playgroud)

如果将虚方法声明为abstract,则它对于从抽象类继承的任何类仍然是虚拟的.继承抽象方法的类无法访问方法的原始实现 - 在前面的示例中,类F上的DoWork无法在类D上调用DoWork.这样,抽象类可以强制派生类为虚方法提供新方法实现.

  • 如果我做了'F ff = new F(); D dd = ff为D; dd.DoWork(0);`?那不会叫'D`的实施吗?如果这是真的,我可以将`F`的'DoWork(int i)'代码放入`D dd = this作为D; dd.DoWork(ⅰ);`?那会叫'D`的实施吗? (2认同)
  • 与任何虚拟成员一样,@ Blueriver将调用实际对象的实现,因此在这种情况下,它将调用F的实现。 (2认同)

gho*_*ord 44

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

public abstract class Base
{
    public abstract override string ToString();
}
Run Code Online (Sandbox Code Playgroud)

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


Eri*_*ert 12

有趣的是,C#编译器的Roslyn版本中有一个抽象的覆盖方法,我发现它很奇怪,可以写一篇文章:

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


Jon*_*Jon 6

想象一下,SecondAbstract它处于三级层次结构的中间,它希望从其基础实现一些抽象方法,FirstAbstract同时留下一些其他方法X从其子级实现ThirdAbstract.

在这种情况下,由于它不想提供实现,SecondAbstract因此被迫装饰方法X. abstract同时,它被强制装饰它,override因为它没有定义新的方法X,但是想要将实现X的责任转移给它的孩子.因此,abstract override.

通常,概念由正交建模abstract并且override是正交的.第一个强制派生类来实现方法,而第二个派生承认方法与基类上指定的方法相同而不是new一个方法.

因此:

  • 既不是关键词:"简单"的方法
  • abstract only:派生类必须实现
  • override only:基类中定义的方法的实现
  • abstract override:派生类必须实现基类中定义的方法