抽象类没有实现接口。

10

我有一个接口,所以类的编写者被迫实现某些方法。 我还想允许一些默认实现的方法,因此我创建了一个抽象类。 问题是所有类都继承自基类,因此我在其中放置了一些辅助函数。

我尝试在抽象基类中写入 : IClass,但是我收到了错误消息,说基类没有实现该接口。 当然,我希望这个类是抽象的,并要求用户实现这些方法。 如果我使用基类作为返回对象,我就无法调用接口类的方法。 如果我使用接口,我就无法访问基类的方法。

我应该如何做,才能既有这些辅助类又强制用户实现某些方法呢?

3个回答

16

确保基类中的方法与接口名称相同,并且它们是公共的。此外,将它们设置为虚拟的,以便子类可以重写而不会隐藏它们。

interface IInterface {
   void Do();
   void Go();
}

abstract class ClassBase : IInterface {

    public virtual void Do() {
         // Default behaviour
    }

    public abstract void Go();  // No default behaviour

}

class ConcreteClass : ClassBase {

    public override void Do() {
         // Specialised behaviour
    }

    public override void Go() {
        // ...
    }

}

6

将接口方法移至抽象类并将其声明为抽象方法,这样派生类就必须实现它们。如果您想要默认行为,请使用抽象类;如果您只想固定签名,请使用接口。这两个概念不可混合。


1

最近我也遇到了同样的问题,但我想出了一种更加优雅(在我看来)的解决方案。它看起来像这样:

public interface IInterface
{
    void CommonMethod();
    void SpecificMethod();
}

public abstract class CommonImpl
{
    public void CommonMethod() // note: it isn't even virtual here!
    {
        Console.WriteLine("CommonImpl.CommonMethod()");
    }
}

public class Concrete : CommonImpl, IInterface
{
    void SpecificMethod()
    {
        Console.WriteLine("Concrete.SpecificMethod()");
    }
}

现在,根据C#规范(13.4.4.接口映射),在将IInterface映射到Concrete类的过程中,编译器还会查找CommonImpl中的CommonMethod,而且它甚至不必在基类中是虚拟的!

与Mau的解决方案相比,另一个重要优点是您不必在抽象基类中列出每个接口成员。


我更喜欢Mau的解决方案。它是明确的,并且可以让编译器为您执行一致性工作。在这个解决方案中,您可能会忘记将IInterface添加到派生类中。 - PlayTank
@PlayTank:...然后最终它会在某些隐式转换上失败,还是在编译时。虽然我同意这个解决方案缺乏一些明确的严谨性。 - vines

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接