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

我有一个抽象的基类:

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() 。 据我所知,这是多余的 – 我很确定删除它会产生零负面影响。

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

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

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

 abstract class Foo { virtual void DoSomeStuff() { //Do Some Stuff } } abstract class Bar : Foo { abstract override void DoSomeStuff(); } 

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


为什么没有编译器警告通知我,我写的内容什么都没做?

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


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

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

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

通过在Bar明确地abstract override它,你可以确保它被Bar的后代看作是抽象的,即使将来在Foo它可能会变成非抽象的。 尽管有这样的改变, Bar的后代将使用相同的合同。