在此示例中,选项2优于1的优点/缺点是什么?
选项1(继承):
public class SalesList : List<Sales>
{
//methods that add extra behavior List<Sales>
}
选项2(组成):
public class SalesList
{
private List<Sales> _list;
//methods that add extra behavior to List<Sales>
}
答案 0 :(得分:2)
选项2的优点是敏捷性。使用组合,您可以选择公开的列表界面的哪些部分。
想象一下,稍后您决定不再从另一个类扩展。到目前为止,您库中的一些用户将使用List提供的方法,因此您需要自己实现所有列表方法:add / addAll / contains / retainAll。这是为简单的销售清单实施的大量方法。
基本上,这归结为Joshua Bloch在Bumper-Sticker API Design中谈到的“当有疑问时,将其遗漏”。 API的每个方面都应尽可能小,但不能小一些。您可以随时添加内容,但不能将其删除。
答案 1 :(得分:2)
Composition的主要缺点是,如果需要提供相同的接口,则需要包装(复制)私有List的所有公共方法,在继承中,所有这些方法都已经可用,但是您无法覆盖其中任何一个都不能覆盖(在C#中它意味着该方法应该标记为'virtual',在Java中它不能被标记为'final')。
在C#3及更高版本中,您可以使用扩展方法,它可以在不真正弄乱层次结构树的情况下提供继承的外观。
答案 2 :(得分:2)
继承允许我们形成类的层次结构,这样父类就是* super *集,并且它的所有子元素都是* sub * set,这允许泛化,专业化并应用substitution principle
答案 3 :(得分:1)
选项1
- 优点 - 继承的所有优点&amp;再利用
- 缺点 - 代码现在向消费者发出信号,表明它是从列表中删除的。如果需要在以后更改,那么所有相关的消费者都将受到影响。
选项2
- 优点 - 销售数据存储的实施细节从消费者中抽象出来。因此,如果实现需要更改(例如,例如字典),该类的使用者将免于这些更改。
- 缺点 - SalesList类现在需要公开其他方法来获取和/或设置内部_list对象。这是需要维护的附加代码。此外,如果内部实现发生变化,您需要注意仍然支持以前的行为......
只是想到了一些想法。
HTH。
答案 4 :(得分:0)
在组合中,您可以在运行时动态更改超类实现。 但是使用继承,您无法在运行时更改超类实现。
在合成中,它取决于您传递给setter的对象类型,它将基于此行为。它将为实施提供更大的灵活性