多接口继承

5

我正在实现一组类和相应的接口,希望每个类都具有一组通用属性和一组专用属性,仅适用于该类。因此,我考虑按以下方式定义接口:

interface ICommon {...}  // Members common to all widgets
interface IWidget1 {...} // specialized members of widget type 1
interface IWidget2 {...} // specialized members of widget type 2

我正在尝试选择接口中的继承还是类中的继承。具体而言,我可以像这样做:

interface IWidget1 : ICommon {...}
interface IWidget2 : ICommon {...}
class Widget1 : IWidget1 {...}
class Widget2 : IWidget2 {...}

...or like this...

class Widget1: ICommon, IWidget1 {...}
class Widget2: ICommon, IWidget2 {...}

有什么明显的理由支持任何一种方式吗?

更新:如果类必须是COM可见的,是否会影响答案?

4个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
6
只有当实现IWidget1的类型必须同时实现ICommon时,您才应选择接口继承。在任一情况下,该类都将单独实现IWidget1和ICommon。唯一的区别是,如果您使IWidget1“派生”自ICommon,则强制要求IWidget1也必须是ICommon。 一个很好的例子是IEnumerable和ICollection。每个ICollection都保证是IEnumerable,因此ICollection派生自IEnumerable。如果成为集合而不可枚举是合法或有意义的话,则ICollection的实现者就不必也实现IEnumerable。 无论您选择哪种方式,都不会影响COM可见性。如果我记得正确,.NET仍将单独导出这些接口。

是的,所有Widget类型都必须实现ICommon接口。这就是为什么要这样做,以强制在每个小部件中实现它。 - Tim Long
1
那么,你肯定应该让IWidget1从ICommon派生。 - Josh

3

使用里氏替换原则来帮助你找到答案。

如果IWidget1可以替换所有以ICommon1为基础的客户端,那么你可以从ICommon1继承IWidget1。 否则,请选择实现多个接口的类。


这不会产生相同的结果吗? - Tim Long
@Tim - 你能详细说明一下吗?我的意思是,如果你可以用一个IWidget1对象替换所有需要ICommon1的代码,并且在你的领域中有一个IWidget1实体是有意义的,那么你可以采用接口继承方法。如果不行,就让同一个类实现多个接口。 - Gishu
好的,我明白你的意思。谢谢。 - Tim Long

1

我认为其他答案中没有考虑到另一个因素。

如果您从ICommon派生出IWidgetX,然后开发出一个既具有IWidget1行为又具有IWidget2行为的小部件,则可以进行多接口实现:

class Widget3 : IWidget1, IWidget2

如果两个接口都派生自ICommon,则您的类中将有两个ICommon实现。这不是一个大问题,可以通过多接口实现来处理,但它会改变逻辑。

另一方面,如果您不从ICommon派生IWidgetX,则可以实现所有三个接口,而无需处理显式实现:

class Widget3 : IWidget1, IWidget2, ICommon

如果您可能需要这样的Widget3类,最好不要从ICommon派生IWidgetX接口


谢谢Tim - 尽管事实证明我并不完全正确! 我深入研究了这个多接口实现的问题,实际上你没有两个ICommon的实现 - 如果你有,那么(ICommon)(new Widget3())的转换将无法解决。 我在这篇博客文章中更详细地描述了这种情况。然而,反对从ICommon派生IWidgetX的论点仍然部分有效。 - Vroomfundel

0

继承取决于类或接口的属性/行为。如果 IWidget1IWidget2 中的行为包括 ICommon 中的所有行为,则可以像 IWidget1:ICommonIWidget2:ICommon 一样继承,而且没有关于 ComVisible 的问题。这只是面向对象编程的概念。


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