子类是否可以实现与其父类相同的接口?

Jes*_*ter 14 c# oop implementation interface

我在今天之前从未遇到过这个问题,并且想知道实现这种行为的惯例/最佳实践是什么.

基本设置是这样的:

public interface IDispatch {
    void Dispatch();
}

public class Foo : IDispatch {
    void IDispatch.Dispatch() {
        DoSomething();
    }
}

public class Bar : Foo {
     ...
}
Run Code Online (Sandbox Code Playgroud)

Bar需要子类化Foo,因为它与Bar共享所有相同的属性,并引入了我需要遇到的2个新属性.我遇到的问题是Foo还需要稍微不同的Dispatch()实现.通常它会被覆盖,但这对于接口方法无效,所以只需要Bar实现IDispatch就可以了,所以我的类定义如下所示:

public class Bar : Foo, IDispatch { .... }
Run Code Online (Sandbox Code Playgroud)

然后只是在Bar中明确实现该接口方法?当我尝试这样做时,我的编译器似乎没有抱怨,但我不确定它是否会导致任何运行时问题,从而解决在未来使用哪种实现或者是否有更好的方法来完成这样的事情.

另外值得一提的是,在我的工作场所,我们使用UML模型中的代码生成,强制所有类设计必须首先从模型完成.代码生成工具是导致接口方法被明确实现的原因(不想辩论它的优点和缺点,这正是我现在被迫处理的事情,因此隐式实现不是一个选项)

Raw*_*ing 15

或者,您可以通过以下两种方式之一执行此操作:

首先,不要显式实现接口:

public class Foo : IDispatch {
    public virtual void Dispatch() {
        whatever();
    }
}

public class Bar : Foo {
    public override void Dispatch() {
        whateverElse();
    }
}
Run Code Online (Sandbox Code Playgroud)

其次,显式实现它,但添加子类可以覆盖的函数:

public class Foo : IDispatch {
    void IDispatch.Dispatch() {
        this.Dispatch();
    }

    protected virtual void Dispatch() {
        whatever();
    }
}

public class Bar : Foo {
    protected override void Dispatch() {
        whateverElse();
    }
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 12

是的,您可以明确重新声明要实现的内容IDispatch,并再次显式实现它Bar.

但是,您将无法调用原始实现Foo.如果你需要这样做,你需要改变Foo使用隐式接口实现和虚方法(可以重写然后用base.Dispatch()in 调用Bar)或者让Foo实现调用成为受保护的虚拟方法,你再次覆盖它Bar.

  • @JesseCarter:再次,听起来像'Bar`可能不应该首先从'Foo`派生出来. (2认同)
  • @JesseCarter:也许您应该使用组合而不是继承-也许Bar应该*包含* Foo以共享实现,但不要假装它会像* Foo那样起作用。 (2认同)