Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Inheritance 在需要向列表中添加行为的情况下,使用组合比使用继承有什么优势<>;?_Inheritance_Oop_Composition - Fatal编程技术网

Inheritance 在需要向列表中添加行为的情况下,使用组合比使用继承有什么优势<>;?

Inheritance 在需要向列表中添加行为的情况下,使用组合比使用继承有什么优势<>;?,inheritance,oop,composition,Inheritance,Oop,Composition,在本例中,选项2与选项1相比有哪些优点/缺点 备选案文1(继承): 公共类销售列表:列表 { //添加额外行为列表的方法 } 备选案文2(组成): 公共类销售列表 { 私人名单(private List);; //向列表中添加额外行为的方法 } 选项2的优点是灵活性。使用composition,您可以选择公开列表界面的哪些部分 想象一下,稍后您决定不再从另一个类扩展。到目前为止,您库的一些用户已经使用了List提供的方法,所以您需要自己实现所有List方法:add/addAll/contain

在本例中,选项2与选项1相比有哪些优点/缺点

备选案文1(继承):

公共类销售列表:列表
{
//添加额外行为列表的方法
}
备选案文2(组成):

公共类销售列表
{
私人名单(private List);;
//向列表中添加额外行为的方法
}

选项2的优点是灵活性。使用composition,您可以选择公开列表界面的哪些部分

想象一下,稍后您决定不再从另一个类扩展。到目前为止,您库的一些用户已经使用了List提供的方法,所以您需要自己实现所有List方法:add/addAll/contains/retainal。对于一个简单的销售列表,有很多方法需要实现

基本上,这可以归结为约书亚·布洛赫(Joshua Bloch)在书中提到的“当有疑问时,请忽略它”。API的每个方面都应该尽可能小,但不能更小。您可以随时在以后添加内容,但不能将其删除。

选项1
-优点-继承和重复使用的所有优点
-缺点-代码现在向消费者发出信号,表明它已从列表中删除。如果以后需要更改,则所有相关消费者都将受到影响

选项2
-优点-销售数据存储的实现细节从消费者那里抽象出来。因此,如果实现需要更改(例如字典),类的使用者将不受这些更改的影响。
-缺点-SalesList类现在需要公开额外的方法来获取和/或设置内部列表对象。这是需要维护的附加代码。此外,如果内部实现发生变化,您需要注意仍然支持以前的行为

只是我想到的一些想法


HTH.

组合的主要缺点是,如果需要呈现相同的接口,则需要包装(复制)私有列表中的所有公共方法,在继承中,所有方法都已可用,但不能覆盖任何不可覆盖的方法(在C#中表示该方法应标记为“virtual”,在Java中不能标记为“final”)


在C#3及更高版本中,您可以使用扩展方法,这种方法在不破坏层次结构树的情况下提供继承的外观。

在组合中,您可以在运行时动态更改超类实现。 但是使用继承不能在运行时更改超类实现


在组合中,它取决于您传递给setter的对象的类型,并且它将基于该类型进行操作。它将在实现上提供更大的灵活性。

继承允许我们形成类的层次结构,例如父类是*超级*集,其所有子类都是*子*集,从而允许泛化、专门化和应用

一个更大缺点的可能重复是,一个人不能将
SalesList
传递给任何编写为期望
List
或generic
List
的方法。重写所有
List
方法可能很烦人,但几乎不可能。如果一个没有代码的方法期望
>List
,使用该方法可能很困难或不可能。泄漏对内部列表的引用似乎可以解决该问题,但会产生更多的问题。由于List的许多方法都是非虚拟的,因此派生类无法改变其行为;无论做什么,都可能会被卡住。
public class SalesList : List<Sales>
{
    //methods that add extra behavior List<Sales>
}
public class SalesList 
{
    private List<Sales> _list;
    //methods that add extra behavior to List<Sales>
}