如何在没有继承的情况下设计控制树/层次结构?

时间:2008-12-12 17:38:09

标签: oop inheritance

我知道回复 Prefer composition over inheritance 并且我意识到作文优于继承的优点。

但是有些情况下继承确实可以起到很好的作用。这是对继承层次结构的错误使用导致与重用相关的所有问题。

以下列控件为例...

Button/Textbox/Combobox/ListBox/Grid etc.

通常它们实现为

public class Control
{
    ...
}


public abstract class TextBoxBase : control
{
    ....
}

public class TextBox : TextBoxBase
{
    ....
}

public abstract class ButtonBase: control
{
    ....
}

public class Button: ButtonBase
{
    ....
}


public class TextBox : TextBoxBase
{
    ....
}


public class NumericTextBox: TextBox
{
    ....
}

注意:UI和功能都可以重复使用。

我可能错了或部分正确。你的想法只会帮助我提高对这个主题的理解。

如何在不使用继承的情况下设计控件模型/层次结构,您认为哪一个更好?

请考虑易用性,也可以使用IDE进行此控制。

P.S:这个问题的灵感来自this question

3 个答案:

答案 0 :(得分:2)

首选组合与在任何情况下强制执行都不一样。要添加到UI示例中,我要说Java和.NET都可以从流中使用继承层次结构中受益。

我建议您查看Windows Presentation Foundation的继承树 - 这是一个相对现代的UI工具包,专为组合而设计。这可以实现奇怪而奇妙的东西 - 比如包含更多按钮等的按钮。有时(如在该示例中)它将是无用的 - 但是通用设计是强大的。

我不是说我很理想 - 我也不会声称对WPF非常了解 - 但这是一个有趣的起点。

我应该指出,即使在WPF中继承也会被广泛使用 - 但与(比如说)WinForms完全不同。

答案 1 :(得分:1)

您将使用一系列委托来实现传统上在父类中的功能。假设Control类包含基本的绘图函数(即paint()) - well将成为BasicControlDelegate或类似的,并且将通过引用BasicControlDelegate创建“子类”,BasicControlDelegate将用于所有“继承”功能。

如果要按原样使用父/委托功能,则在每个“子类”中创建一个paint()方法,该方法只是在委托上调用相同的方法。如果要更改功能,可以创建不同的实现。

TextBoxBase可能有一个paint()实现,它由TextBox直接使用,但也许NumericTextBox有自己的paint()实现。

我认为要点主要是:

  • 继承类似于具有对“父对象”的隐式引用的合成(当然,只有一个真实对象)。
  • 通过继承,您可以默认继承并公开每个公共方法,如果愿意,可以覆盖它。
  • 使用合成时,默认情况下不显示任何内容,并且必须包装要公开的每个方法。

答案 2 :(得分:0)

当所有任务都处于相同的角色时,继承会更好。