如何仅部分实现具有抽象类的接口时满足编译器?

Sta*_*dog 22 c# abstract-class

这里有一个名为的界面IFish.我想用一个抽象的class(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; }
}
Run Code Online (Sandbox Code Playgroud)

我还没有发现如何使编译器满意,同时仍然实现了强制从WalkingFishCommon派生的类来实现该Swim()方法的目标.特别令人困惑的是(1)和(2)之间的差异,其中编译器在Swim()没有标记为抽象的抱怨之间交替,并且在下一次呼吸中抱怨它不能被标记为抽象.有趣的错误!

有帮助吗?

Ser*_*rvy 31

只是声明Swimabstract并且不要尝试为它使用显式接口声明(即删除IFish).

abstract class WalkingFishCommon : IFish
{
    public bool CanWalk { get { return true; } }
    public abstract bool Swim();
}
Run Code Online (Sandbox Code Playgroud)

  • 事实证明,我没有具体的理由去做"明确"的实施.我只是遇到了一个误解 - 我认为需要在派生方法声明中指定接口名称,或者最终使用相同名称的无关方法.所以这个答案澄清并解决了这个问题.谢谢 (2认同)
  • @Stabledog如果接口方法是显式实现的,那么你只能*通过接口类型的标识符调用该方法; 如果您没有显式实现接口的类实例,则必须先将其类型化为接口,然后才能调用这些方法.根据我的经验,人们很少使用显式实现,除非他们需要.请参阅:http://msdn.microsoft.com/en-us/library/vstudio/ms173157.aspx (2认同)

dtb*_*dtb 26

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

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

    public bool Swim() { return ...; }
}
Run Code Online (Sandbox Code Playgroud)

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

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

    public abstract bool Swim();
}
Run Code Online (Sandbox Code Playgroud)

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

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

    protected abstract bool Swim();

    bool IFish.Swim() { return Swim(); }
}
Run Code Online (Sandbox Code Playgroud)


Tho*_*que 9

如果您不需要显式实现接口,则可以执行以下操作:

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

}
Run Code Online (Sandbox Code Playgroud)

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

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

    protected abstract bool CanWalkCore { get; }
    protected abstract bool SwimCore();

}
Run Code Online (Sandbox Code Playgroud)