type
date
status
slug
summary
tags
category
icon
password
网址
5.通过组合体现 "有一个" 或 "用...来实现"
使某个类的对象成为另一个类的数据成员,从而实现将一个类构筑在另一个类之上,这一过程称为
"组合“,分层;
公有继承
C++面向对象编程中一条重要的规则是:公有继承意味着 "是一个" 。
组合
通过组合来体现 "有一个" 或 "用...来实现"。
例如,“汽车有一个发动机 或 汽车用发动机来实现 ” (has-a) 关系可以用单一组合表示为:
同样的“有一个”关系也能用私有继承表示:
聚合关系:通过聚合体现 "有一个" 或 "用...来实现"。 整体类与局部类之间松耦合,相互独立。
组合关系:通过组合体现 "有一个" 或 "用...来实现"。组合是一种耦合度更强的关联关系。存在组合关系的类表示“整体-部分”的关联关系,“整体”负责“部分”的生命周期,他们之间是共生共死的;并且“部分”单独存在时没有任何意义。
只有一个部分时,可以使用私有继承,或成员数据方式实现组合;
如果有多个部分时, 使用成员数据方式实现组合。
//-------------------------------
私有继承: 要表示类之间 "用...来实现" 的关系,可以选择是通过私有继承实现。现在这种情况下,这
一技术就比分层更有优势,因为通过它可以让你告诉别人:Engine使用起来不安全,它只能用来实现其
它的类。具体做法是将Engine 的成员函数声明为保护类型:
// ------------------------------------
公有继承与组合的区别
继承与组合都是面向对象中代码复用的方式。
公有继承
公有继承:父类的内部细节对子类可见,其代码属于白盒式的复用;
例如: class Person ; class Student;
公有继承的优缺点
优点:
支持扩展,通过继承父类,可以设计较为复杂的系统,体现了由简单到复杂的认识过程。
易于修改被复用的代码。
缺点:
代码白盒复用,父类的实现细节暴露给子类,破坏了封装性。
当父类的实现代码修改时,可能使得子类也不得不修改,增加维护难度。
子类缺乏独立性,依赖于父类,耦合度较高。
不支持动态拓展,在编译期就决定了父类。
组合和私有继承
组合:意味着 "用...来实现"; 对象之间的内部细节不可见,其代码属于黑盒式复用。
私有继承意味着 "用...来实现"; 是组合关系,父类的内部细节对子类不可见,其代码属于黑盒式复用。
组合的优缺点
优点:
代码黑盒复用,被包括的对象内部实现细节对外不可见,封装性好。
整体类与局部类之间松耦合,相互独立。
支持扩展
每个类只专注于一项任务
支持动态扩展,可在运行时根据具体对象选择不同类型的组合对象(扩展性比继承好)。
缺点:
创建整体类对象时,需要创建所有局部类对象。导致系统对象很多。
公有继承与私有继承和组合如何选择?
在对象分析时明确具有是一个(is - a) 的关系,使用公有继承。
在对象分析时明确具有 "有一个" 或 "用...来实现"关系,使用组合和私有继承。
私有继承和组合如何选择?
答案很简单:尽可能地使用组合,必须时才使用私有继承。什么时候必须呢?这往往是指有保护成员和/或虚函数介入的时候考虑考虑使用私有继承。
//私有继承在编码过程中就要指定具体的父类,其关系在编译期就确定,而组合的关系一般在运行时确定。