我应该将List <t>子类化还是将其作为属性?</t>

时间:2008-10-20 06:46:12

标签: inheritance oop

在过去的几个月里,我经常遇到这个问题,在此期间我一直在构建这个系统。场景是这样的:我有这种对象,本质上是一个其他对象的列表,但有一些特定于其性质的其他属性。例如:

  • 班级Tests
    • 包含许多Test个对象
    • 有属性:
      • DefaultTimeouts
      • DefaultNumberOfTries

我应该拥有此类子类List<Test>还是应该从Object继承它,只需将列表作为属性放在其他字段旁边?

我知道这可能有点主观,个人品味可能在这里发挥作用,但我全心全意地想知道你对此的看法。

8 个答案:

答案 0 :(得分:12)

与大多数答案相反,在大多数情况下,我不会从List继承。我发现继承一个类来重用功能通常会在以后引起问题。

我通常只有一个List(或IList)类型的属性,它返回对列表的引用。通常你只需要一个获得房产。您可以通过选择使用.AsReadOnly()返回列表的只读版本或仅将列表公开为IEnumerable来控制对列表的访问。

如果我希望测试列表,我通常会实现IList并为IList的实际实现调用内部List字段。这是一个更多的工作,并导致更多的代码要维护,但我发现这比继承List更好的可维护性只是为了它的实现。

答案 1 :(得分:6)

List&lt; T&gt;中的子类。如果您将List generic作为属性,则不能将其封装为子类。

如果它看起来像List&lt; T&gt;并且它听起来像List&lt; T&gt;,它可能是List&lt; T&gt;。

我称之为TestCollection。

答案 2 :(得分:1)

如果它真的完成List所做的一切,并且所有List函数都会以直观的方式对Tests对象起作用,从而得到正确的结果,那么在我看来它应该只是List<Test>的子类。

否则,您将只拥有一个包含大量方法的类,这些方法只是在实例中的List<Test>变量上调用同名方法。这只是List<Test>类本身的不完美扩展。

答案 3 :(得分:1)

继承通常映射到“is-a”关系。由于您的容器列表,但是还有其他一些东西,我将从List继承并将您的其他属性添加到您的子类中。

答案 4 :(得分:1)

我认为你所拥有的只是一个简单的“测试列表”,因为你需要更多东西。我建议您将其称为TestSuite并将列表作为属性。与继承相比, Has-a 更容易维护。

一般来说,我会非常小心地继承像List这样的东西。

答案 5 :(得分:1)

在阅读答案时,似乎关键问题是你的对象真正一个列表的长度?所以也许在继承的危险和组合的透明度不足是将List<Test>作为私有后端,并且只公开将要使用的方法。

答案 6 :(得分:0)

在您的示例中,您说“类测试包含许多测试对象”,而不是“类测试是测试对象的集合”。 IMO除非你需要为这个类提供类似List的接口,否则没有必要在这个场景中继承List。

但是,答案实际上取决于Tests类的上下文。如果它的行为类似于List,并且将在期望列表对象的上下文中使用,则从List继承。

请注意,继承比组合更难维护。

另外,我会将Tests重命名为TestCollection(如果你是子类List),或者像TestUnit那样重命名(如果它包含Test类列表。

答案 7 :(得分:0)

“赞成组合而不是继承”总是一个很好的经验法则。使用此类的方法是使用所有List方法以及添加的方法还是仅添加的方法?