15

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

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

我应该有这个类的子类List<Test>还是应该让它继承自Object,只是将列表作为其他字段旁边的属性?

我知道这可能有点主观,个人品味可能会在这里起作用,但我非常想知道您对此的看法。

4

8 回答 8

12

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

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

在我希望 Tests成为列表的情况下,我通常实现 IList 并为 IList 的实际实现调用内部 List 字段。这需要更多的工作,并导致需要维护更多的代码,但我发现这比仅仅为了实现而继承 List 更易于维护。

于 2008-10-20T07:34:16.643 回答
6

List<T> 的子类。如果您将 List 泛型作为属性,那么它就没有像子类那样被很好地封装。

如果它看起来像 List<T> 并且听起来像 List<T>,那么它可能是 List<T>。

我称之为TestCollection。

于 2008-10-20T06:52:19.240 回答
1

如果它确实做了所有 aList会做的事情,并且所有List函数都会Tests以直观的方式作用于对象并给出正确的结果,那么在我看来它应该只是 subclass List<Test>

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

于 2008-10-20T06:48:20.993 回答
1

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

于 2008-10-20T06:49:47.217 回答
1

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

一般来说,我会非常小心地继承类似 a 的东西List

于 2008-10-20T06:57:12.770 回答
1

在阅读答案时,关键问题似乎是你的对象真的是一个列表的长度是多少?因此,在继承的危险和组合的缺乏透明度之间,一个很好的折衷方案是将 aList<Test>作为私有后端并仅公开将要使用的方法。

于 2008-10-20T07:07:25.993 回答
0

在您的示例中,您说“类测试包含许多测试对象”,而不是“类测试是测试对象的集合”。IMO 在这种情况下没有必要对 List 进行子类化,除非您需要为此类提供类似 List 的接口。

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

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

此外,我会将 Tests 重命名为 TestCollection(如果您将 List 子类化)或类似 TestUnit 的名称(如果它包含 Test 类的列表。

于 2008-10-20T06:51:53.733 回答
0

“优先组合优于继承”始终是一个很好的经验法则。使用此类的方法是使用所有 List 方法以及您添加的方法还是仅使用您添加的方法?

于 2008-10-20T06:53:23.340 回答