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

问题描述 投票:46回答:7

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

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#编译器允许编写'抽象覆盖'。这不是多余的吗?应该是一个编译时错误来做这样的事情。是否适用于某些用例?

谢谢你的关注。

c# override abstract
7个回答
59
投票

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

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.
    }
}

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


43
投票

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

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

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


12
投票

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

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


6
投票

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

在这种情况下,SecondAbstract被迫用abstract装饰方法X,因为它不想提供实现;与此同时,它被迫用override来装饰它,因为它没有定义一个新的方法X,但是想要将实现X的责任转移给它的孩子。因此,abstract override

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

因此:

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

0
投票

这样做是因为在子类中,您不能使用与基类同名的abstract方法。 override告诉编译器你正在覆盖基类的行为。

希望这是你正在寻找的。


0
投票

如果你没有在SomeMethod中将abstract override声明为SecondAbstract,编译器会希望该类包含该方法的实现。使用abstract override很明显,实现应该是从SecondAbstract派生的类,而不是SecondAbstract本身。

希望这可以帮助...


0
投票

此设计模式称为模板方法模式。

Wikipedia page on Template Methods

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

  • 移动()
  • 攻击()
  • 撤退()
  • 休息()

等等...

© www.soinside.com 2019 - 2024. All rights reserved.