为什么我可以抽象覆盖抽象方法?

时间:2014-07-16 22:50:52

标签: c#

我有一个抽象的基类:

abstract class Foo
{
    virtual void DoSomeStuff()
    {
        //Do Some Stuff
    }

    abstract void DoSomeCrazyStuff();
}

另一个抽象类派生自:

abstract class Bar : Foo
{
    abstract override void DoSomeStuff();

    abstract override void DoSomeCrazyStuff();
}

我理解你为什么要抽象覆盖DoSomeStuff() - 它需要一个新的实现来进一步派生类。但我无法弄清楚你为什么要抽象覆盖DoSomeCrazyStuff()。据我所知,这是多余的 - 我很确定删除它会产生零负面影响。

是否有一些用例,抽象覆盖在抽象上有用吗?如果没有,为什么没有编译器警告通知我,我写的东西什么都没做?

2 个答案:

答案 0 :(得分:3)

  

为什么我可以抽象覆盖抽象方法?

对于初学者来说,没有任何实际的理由可以阻止它。如果它产生了编译器错误,那么所做的就是让类变得更脆弱。例如:

abstract class Foo
{
    virtual void DoSomeStuff()
    {
        //Do Some Stuff
    }
}

abstract class Bar : Foo
{
    abstract override void DoSomeStuff();
}

如果抽象的抽象覆盖是非法的,将Foo上的DoSomeStuff更改为abstract现在会阻止Bar编译。抽象覆盖是多余的,但是没有潜在的负面影响,因此编译器可以使用它。


  

为什么没有编译器警告通知我,我写的内容没有任何作用?

编译器会为某些代表风险的事物生成警告:非显式方法隐藏,无法访问的代码,使用过时的方法等。不必要的抽象覆盖的唯一“问题”可能表明代码没有被有效写入。这不是编译器所关心的。


  

是否有一些用例,抽象覆盖在抽象上有用?

不是功能性的。但是,有一些用例可能会故意这样做:

  • 提高代码的“可读性”。具有冗余抽象覆盖将提醒该方法是抽象的。
  • 如果将来对基类的更改包括提供虚拟实现,则可以预先阻止某些类访问该基类。
  • 如果抽象覆盖是多余的,因为基类已从虚拟实现更改为抽象,则可以安全地保留它。

答案 1 :(得分:2)

通过abstract override明确地Bar,确保Bar s后代将其视为抽象的,即使将来Foo它可能会变成非抽象的。尽管有这样的变化,Bar的后代将使用相同的合同。