))
C面向对象核心什么是组合Composition——“继承”之外的另一种代码复用方式对于小学生可以先记一句话组合就是一个类里面包含另一个类的对象让它们一起完成工作。简单来说继承我是你is-a组合我拥有你has-a一、先回忆一下继承我们之前学习class Dog : public Animal { };意思Dog 是一种 Animal。关系Animal | | Dog英语Dog is an Animal也就是狗是一种动物。二、什么是组合现在换一种情况。比如汽车。汽车里面有什么发动机轮子方向盘我们可以写class Engine { }; class Car { Engine engine; };这里Car里面有一个Engine对象。关系Car | | Engine英语Car has an Engine意思汽车拥有一个发动机。这就是组合。三、组合的本质组合就是一个类把另一个类作为自己的成员变量。例如class Student { }; class School { public: Student stu; };表示学校里面有学生。不是学校是学生。所以不能class School : public Student { };四、继承和组合的最大区别这是面向对象考试非常喜欢考的。继承表示是一种英文is-a例如狗 是 动物所以Dog : Animal组合表示拥有一个英文has-a例如汽车 有 发动机所以Car { Engine engine; };五、生活中的例子例1人和心脏错误class Heart : public Person { };为什么因为心脏不是人。关系Person has a Heart正确class Heart { }; class Person { public: Heart heart; };例2电脑和CPU错误class CPU : public Computer { };因为CPU不是电脑。正确class CPU { }; class Computer { public: CPU cpu; };六、组合的代码例子我们设计一个小机器人。电池类class Battery { public: void charge() { cout充电endl; } };机器人类class Robot { private: Battery battery; public: void work() { battery.charge(); cout机器人工作endl; } };使用int main() { Robot r; r.work(); }输出充电 机器人工作为什么 Robot 可以调用 charge因为Robot里面有Battery battery;七、组合对象的创建顺序这个非常重要。例如class Engine { public: Engine() { cout发动机创建endl; } }; class Car { public: Engine e; Car() { cout汽车创建endl; } };执行Car c;输出发动机创建 汽车创建为什么因为汽车里面先有发动机。创建过程创建Car ↓ 先创建成员对象Engine ↓ 再执行Car构造函数八、组合中的析构顺序和继承类似创建成员对象 ↓ 自己销毁反过来自己 ↓ 成员对象例如汽车析构 ↓ 发动机析构口诀构造先里面后外面析构先外面后里面九、组合和继承什么时候用这是面向对象设计的核心。情况1如果满足A是一种B用继承。例如Dog 是 Animal代码Dog : Animal情况2如果满足A拥有B用组合。例如Car拥有Engine代码Car { Engine e; }十、为什么很多时候推荐组合在实际大型程序中很多工程师更喜欢优先使用组合而不是继承。为什么因为继承关系比较强。例如class Dog : Animal表示Dog永远是一种Animal。如果以后发现狗也可以飞又增加FlyingAnimal继承关系可能变复杂。组合更灵活例如机器人需要电池摄像头轮子可以class Robot { Battery battery; Camera camera; Wheel wheel; };需要什么加什么。十一、组合和继承的内存区别继承class Dog : Animal { };对象Dog对象 ---------------- | Animal部分 | ---------------- | Dog部分 | ----------------组合class Car { Engine e; };对象Car对象 ---------------- | Engine对象 | ---------------- | Car自己的部分 | ----------------十二、和之前“类必须定义才能继承”的联系我们之前讲class Animal; class Dog:public Animal { };为什么错误因为继承需要知道Animal完整结构但是组合class Engine; class Car { Engine* e; };可以。因为指针只需要知道名字。但是class Car { Engine e; };不可以。因为Car里面真正包含Engine。十三、小学生记忆口诀继承我是你 is-a Dog 是 Animal代码class Dog:public Animal组合我有你 has-a Car 有 Engine代码class Car { Engine e; };十四、面向对象三大关系总结C里面常见三种关系关系含义例子C实现继承是一种狗是动物class Dog:Animal组合拥有一个车有发动机成员变量依赖使用一下医生使用工具函数参数最后给学生一句最重要的话继承解决“像不像”的问题组合解决“有没有”的问题。判断方法看到“它是一个……”→ 想继承。看到“它有一个……”→ 想组合。这也是将来学习设计模式、STL源码、游戏开发、大型软件设计的基础。