使用抽象类而不是接口

时间:2018-03-02 04:27:23

标签: c# inheritance interface abstract-class member

我用C#编程。我的班级设计变得相当复杂。在许多情况下,我试图在可能的情况下避免继承;例如,我更喜欢" has-a"设计代替" is-a"设计。

我相信我的设计会遇到指示的最终设计是多重继承的情况。我知道多重继承的禁忌,而且Java和C#都不允许这样做。

我会尝试编写一些伪代码来说明我的情况。

让我们在我的开发应用程序中说,我想区分屏幕上可见的项目和不是的项目。我将制作一个类" DisplayObject"这是要显示的所有项目的根类。

我有一个"按钮"然后将继承自DisplayObject的类。

class Button : DisplayObject

但是,我想创建一个抽象类" Clickable"。 (我知道,在这一点上,有些人可能会说"使用界面"例如,IClickable。但就目前而言,将该建议放在一边。)

Clickable的观点,即作为一个抽象类,我想提供一些默认功能。 Button类(显然)不能从DisplayObject和Clickable继承。

一个想法可能是使Clickable继承自DisplayObject,然后Button继承自Clickable。

class Clickable : DisplayObject

class Button : Clickable

这似乎是一个好主意,因为我想创建一个也可点击的Link类。 " LINK" class可以从Clickable继承。

没有详细说明什么样的"臭的"这可能导致代码增长,我似乎正在努力使用Decorator模式。但是从我记忆中,Decorator模式实现了:

class Button : ClickableDecorator<DisplayObject>

我也不喜欢。特别是如果我计划拥有很多装饰&#34;我的班级定义的补充。

所以我可能会倾向于尝试将伪装饰器列表作为Button类的成员:

public List<Decorator> Decorators { get; set; }

但这仍然会让人感到困惑。

总结(希望找到解决方案):

  1. 我不想做太多事情&#34; Prefactoring&#34; (重构之前完成 实际上适得其反的时间。)
  2. 我不想那么简单的推荐解决方案 会引起很多头疼,这将需要一个 很多重构。
  3. 基本上,我希望有一个&#34; has-a&#34;解决方案 多个&#34;是-a&#34;困境。
  4. 感谢您阅读此内容!

1 个答案:

答案 0 :(得分:1)

我很好地知道你的代码是否闻到了嗅觉。如果认为它闻起来有味道,那么其他所有半工作鼻子的人都认为它闻起来也很有气味。

听起来像你在闻一些东西,它不是很好......你可以尝试隐藏气味,并为其他人找出有关挥之不去的气味的借口,或者你可以开始研究问题的核心(imho)由以下评论代表:

  

但是,我想创建一个抽象类&#34; Clickable&#34;。 (我知道,在这一点上,有些人可能会说&#34;使用界面&#34;例如,IClickable。但就目前而言,将该建议放在一边。)

为什么要放在一边?这是一个非常有效的思考(我不是说做它,我说认为它)。

正如this answer所述,界面是关于描述可以做,继承描述是-a 。所以一个按钮&#34;是&#34; DisplayObject和&#34; can-do&#34; Click()是考虑它的一种方式,也许你应该考虑。

class Button : DisplayObject, IClickable

这很方便,因为它允许您例如向List<IClickable>添加按钮和其他可点击以进行迭代,或者设计一个处理器,该处理程序可以执行任何实现IClickable的操作。

考虑它的另一种方法是使用多层继承:

class ClickableDisplayObject : DisplayObject { ... }

class Button : ClickableDisplayObject { ... }

所有可显示的东西都不必直接来自DisplayObject

如果不知道您要解决的具体问题,很难再给出更多建议,但最后我要说:

  1. 如果您担心所谓的预制,并且您不想进行太多的重构,那么请仔细查看为什么您做出了决定到目前为止,你已经做过了,并且考虑到这可能存在这样的原因:尽管多年来有数十亿行代码,但大多数C#世界并没有为你的确切问题而烦恼。如果您认为您需要多重继承,那么您就会错误地思考它。
  2. 暂时忘记 has-a 。你在顶部和底部再次提到它,但我还没有看到它是如何实际问题的一个很好的解释,以及为什么继承和接口可以在一个漂亮,干净的情况下为你解决它方式。
  3. 如果您不愿意遵循良好的编码原则,例如SOLID,特别是&#34; S&#34,那么将会有一种干净(足够)的方式来实现它,而不需要多重继承。 ;部分。它可能意味着更多样板代码,更多源文件,更多类或其他一些虚假问题,但它将无限可维护,可重复使用,可测试,并且您很快会注意到原始气味已经消失的某个地方...
相关问题