为什么我可以抽象重写一个抽象方法

本文关键字:一个 抽象方法 我可以 抽象 重写 为什么 | 更新日期: 2023-09-27 18:13:13

我有一个抽象基类:

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();
}

如果abstract上的abstract override是非法的,将Foo上的DoSomeStuff更改为abstract将会阻止Bar编译。抽象重写是多余的,但没有潜在的负面影响,所以编译器可以接受。


为什么没有一个编译器警告告诉我我所写的什么都不做?

编译器对某些表示风险的事情产生警告:非显式方法隐藏、不可访问的代码、使用过时的方法等。不必要的抽象重写可能表明的唯一"问题"是代码没有有效地编写。这不是编译器关心的。


是否有一些用例,抽象覆盖抽象做一些有用的东西?

没有功能。然而,在一些用例中,您可能有意这样做:

    为了提高代码的"可读性"。拥有冗余的抽象重写将作为一个提醒,提醒该方法是抽象的。
  • 如果将来对基类的更改包括提供虚拟实现,您可以先发制人地阻止某些类访问该基类。
  • 如果抽象重写是多余的,因为基类从虚拟实现变成了抽象,它可以被安全地保留。

通过显式abstract overrideBar你确保它将被视为抽象的Bar的后代,即使在Foo的未来它可能会变成一个非抽象的一个。尽管如此,Bar的后代将使用相同的合同。