面向对象编程(OOP)中组合与继承的区别

组合与继承都能够提高代码的重用性,那么问题来了,组合与继承的区别是什么?什么时候用组合,什么时候用继承?下面是我百度到的,仅供参考:

类的组合和继承一样,是软件重用的重要方式。组合和继承都是有效地利用已有类的资源。但二者的概念和用法不同。通过继承建立了派生类与基类的关系,它是一种 “是(is a)”的关系,如“白猫是猫”,“白马是马”,派生类是基类的具体化实现,是基类中的一 种。通过组合建立了成员类与组合类(或称复合类)的关系,换句话说就是"有(has a)的关系".在功能上来看,它们都是实现系统功能重用,代码复用的最常用的有效的设计技巧,都是在设计模式中的基础结构。相信大家已了解的,类继承允许我们根据自己的实现来覆盖重写父类的实现细节,父类的实现对于子类是可见的,所以我们一般称之为白盒复用。对象持有(其实就是组合)要求建立一个号的接口,但是整体类和部分类之间不会去关心各自的实现细节,即它们之间的实现细节是不可见的,故成为黑盒复用。继承是在编译时刻静态定义的,即是静态复用,在编译后子类和父类的关系就已经确定了。而组合这是运用于复杂的设计,它们之间的关系是在运行时候才确定的,即在对对象没有创建运行前,整体类是不会知道自己将持有特定接口下的那个实现类。在扩展方面组合比集成更具有广泛性。继承中父类定义了子类的部分实现,而子类中又会重写这些实现,修改父类的实现,设计模式中认为这是一种破坏了父类的封装性的表现。这个结构导致结果是父类实现的任何变化,必然导致子类的改变。然而组合这不会出现这种现象。对象的组合还有一个优点就是有助于保持每个类被封装,并被集中在单个任务上(类设计的单一原则)。这样类的层次结构不会扩大,一般不会出现不可控的庞然大类。而累的继承就可能出来这些问题,所以一般编码规范都要求类的层次结构不要超过3层。组合是大型系统软件实现即插即用时的首选方式。最后还说一句,“优先使用对象组合,而不是继承”是面向对象设计的第二原则。在OOP中,组合和继承是扩展对象功能的两大利器,GoF在《设计模式》中指出OO设计的一大原则就是:优先使用对象组合,而不是类继承。但并不是说什么都设计都用组合,只是优先考虑组合,更不是说继承即使不好的设计,应该用组合,应为他们之间也有各自的优势。下面是他们之间的优缺点比比较表:



组 合 关 系
优点:不破坏封装,整体类与局部类之间松耦合,彼此相对独立
优点:具有较好的可扩展性
优点:支持动态组合。在运行时,整体对象可以选择不同类型的局部对象
优点:整体类可以对局部类进行包装,封装局部类的接口,提供新的接口
缺点:整体类不能自动获得和局部类同样的接口
缺点:创建整体类的对象时,需要创建所有局部类的对象

继 承 关 系
缺点:破坏封装,子类与父类之间紧密耦合,子类依赖于父类的实现,子类缺乏独立性
缺点:支持扩展,但是往往以增加系统结构的复杂度为代价
缺点:不支持动态继承。在运行时,子类无法选择不同的父类
缺点:子类不能改变父类的接口,但子类可以覆盖父类的接口
优点:子类能自动继承父类的接口
优点:创建子类的对象时,无须创建父类的对象

看过这些解释,相信也有了自己的一些想法,当两个类没有任何关系的时候用组合,有关系时 就抽象出来基类,使用继承。

没有更多推荐了,返回首页