在过去的几个月里,我经常遇到这个问题,在此期间我一直在构建这个系统。场景是这样的:我有这种对象,本质上是一个其他对象的列表,但有一些特定于其性质的其他属性。例如:
Tests
:
Test
个对象DefaultTimeouts
DefaultNumberOfTries
我应该拥有此类子类List<Test>
还是应该从Object
继承它,只需将列表作为属性放在其他字段旁边?
我知道这可能有点主观,个人品味可能在这里发挥作用,但我全心全意地想知道你对此的看法。
答案 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方法以及添加的方法还是仅添加的方法?