接口继承 - 一件好事?

时间:2009-05-18 20:16:40

标签: c# inheritance interface language-agnostic

我刚刚第一次使用它 - 考虑:

IGameObject
    void Update()

IDrawableGameObject : IGameObject
    void Draw()

我有一个使用DrawableGameObjects的关卡类 - 我将其改为IDrawableGameObject,以减少耦合和辅助TDD。

但是我当然失去了在没有强制转换的情况下调用Update(..)的能力 - 为了解决这个问题,我使用了继承。我以前从未使用过基于接口的继承 - 除非在这种情况下,我也没有真正找到需要。

我真的不想每次都在我的更新方法中进行转换,因为它每秒调用60次,另一方面foreach(..)可以使用IGameObject的。

有什么建议吗?

修改

我应该添加 - 我之后创建的假单元用于单元测试,然后实现IDrawableGameObject - 这些类现在有很多方法,而不是每个接口只有少数几个。我知道接口必须只有少数几个成员,但是继承会破坏这个规则吗?

由于

5 个答案:

答案 0 :(得分:5)

  

我知道接口必须只是一个   极少数成员

他们需要包含尽可能多的成员来表达这个概念 - 不多也不少。 BCL中有一些非常可怕的界面(尽管你可能会说有些界面过大)。

我认为这绝对是接口继承的可接受用途。

顺便说一句......如果存在仅依赖于接口成员的实现逻辑,请考虑使用扩展方法,以便实现类不需要重复它...例如:

// just a silly example that only uses members of the target type
public static void DrawComplete(this IDrawableGameObject obj, Canvas canvas) {
   obj.Draw(canvas);
   foreach(var child in obj.Children.OfType<IDrawableGameObject>()) {
       child.DrawComplete(canvas);
   }
}

然后所有调用者都获得DrawComplete方法,而不需要重复实现所有实现。

答案 1 :(得分:3)

基于接口的继承在“你应该这样做”方面与正常继承没有什么不同。它仍然表达两种类型之间的“是一种”关系。所以在这种情况下,如果IDrawableGameObject确实是一个IGameObject,那么继承是有意义的。

答案 2 :(得分:0)

以这种方式应用接口继承需要注意的事情是,根接口的添加可以创建大量工作,使接口的实现符合新的更改(在大型项目中)。如果你有多层接口继承,它还可能使得很难判断方法属于哪个接口。

答案 3 :(得分:0)

如果你正在使用IGameObject而且只使用它,那么可以考虑将它们组合到一个接口中。但是,如果您在代码的其他区域中独立使用IGameObject,那么您所做的事情是完全可以接受的。如果可以以这种方式继承,则没有理由在接口中复制方法和属性。

答案 4 :(得分:0)

正如JaredPar所说,接口继承本身并没有错;只要一个是另一个的逻辑基类型,它只是一个实现细节。如果你不能简单地回答这个问题(IDrawableGameObject是否一直是IGameObject?),那么你的模型可能需要更多的重新思考。例如,将您创建的层次结构分成两个独立的IUpdateable和IDrawable接口可能是有意义的;没有什么能阻止单个类实现这两个接口。

在任何一种情况下,如果演员阵容困扰你,你可以考虑保留一个List和一个单独的List,并在创建它们时向其中一个或两个添加对象。这是简化代码还是复杂化代码取决于其他所有内容的组合方式。