当使用抽象类仅部分实现接口时,如何满足编译器的要求

本文关键字:满足 何满足 编译器 抽象类 仅部 接口 实现 | 更新日期: 2023-09-27 18:27:05

我在这里有一个名为IFish的接口。我想用一个抽象类(WalkingFishCommon)来派生它,它提供了一个不完整的实现,这样从WalkingFishCommon派生的类就不必实现CanWalk属性:

interface IFish
{
    bool Swim();
    bool CanWalk { get; }
}
abstract class WalkingFishCommon : IFish
{
    bool IFish.CanWalk { get { return true; } }
    // (1) Error: must declare a body, because it is not marked
    // abstract, extern, or partial
    // bool IFish.Swim();
    // (2) Error: the modifier 'abstract' is not valid for this item
    // abstract bool IFish.Swim();
    // (3): If no declaration is provided, compiler says 
    // "WalkingFishCommon does not implement member IFish.Swim()"
    // {no declaration}
    // (4) Error: the modifier 'virtual' is not valid for this item
    // virtual bool IFish.Swim();
    // (5) Compiles, but fails to force derived class to implement Swim()
    bool IFish.Swim() { return true; }
}

我还没有发现如何让编译器满意,同时仍然实现强制从WalkingFishCommon派生的类实现Swim()方法的目标。特别令人困惑的是(1)和(2)之间的delta,编译器在抱怨Swim()没有标记为抽象和下一次抱怨不能标记为抽象之间交替。有趣的错误!

有什么帮助吗?

当使用抽象类仅部分实现接口时,如何满足编译器的要求

只需将Swim声明为abstract,不要尝试为其使用显式接口声明(即删除IFish)。

abstract class WalkingFishCommon : IFish
{
    public bool CanWalk { get { return true; } }
    public abstract bool Swim();
}

通常,接口是通过在类中为接口的每个成员定义一个公共成员来隐式实现的:

class MyFish : IFish
{
    public bool CanWalk { get { return ...; } }
    public bool Swim() { return ...; }
}

如果您不想为其中一个成员提供实现,您可以简单地将其抽象化:

abstract class FishBase : IFish
{
    public virtual bool CanWalk { get { return true; } }
    public abstract bool Swim();
}

如果你真的需要显式地实现接口,你可以创建两个成员:一个抽象成员必须被派生类覆盖,另一个成员实现接口并将调用转发给第一个成员:

abstract class FishBase : IFish
{
    public virtual bool CanWalk { get { return true; } }
    protected abstract bool Swim();
    bool IFish.Swim() { return Swim(); }
}

如果你真的不需要显式地实现接口,你可以简单地这样做:

abstract class WalkingFishCommon : IFish {
    public abstract bool CanWalk { get; }
    public abstract bool Swim();
}

如果显式实现很重要,可以通过引入受保护的抽象方法来解决问题:

abstract class WalkingFishCommon : IFish {
    bool IFish.CanWalk { get { return CanWalkCore; } }
    bool IFish.Swim() { return SwimCore(); }
    protected abstract bool CanWalkCore { get; }
    protected abstract bool SwimCore();
}

不完全是一个解决方案,但也许你可以做一些类似的事情

interface IWalkingFish
{
    bool CanWalk { get; }
}
interface ISwimmingFish
{
    bool Swim();
}
interface IFish : ISwimmingFish, IWalkingFish
{ }
abstract class WalkingFishCommon : IWalkingFish
{
    bool IWalkingFish.CanWalk { get { return true; } }
}

然后,您可以为抽象类和具体类使用不同的接口。