//############################################################################
/*
* 代码复用: 继承 vs 组合
*/
//继承实现代码复用
class BaseDog {
...
... // 公共的操作
};
class BullDog : public BaseDog {
... // 调用公共操作,执行更多任务
};
class ShepherdDog : public BaseDog {
... // 调用公共操作,执行更多任务
};
// 组合实现代码复用
class ActivityManager {
... // 公共操作
};
class Dog {
...
};
class BullDog : public Dog {
ActivityManager* pActMngr;
... // 通过pActMngr调用公共操作
};
class ShepherdDog : public Dog {
ActivityManager* pActMngr;
... // 通过pActMngr调用公共操作
};
/*
* 代码复用: 组合优于继承
*
* 1. 复用者和被复用者之间具有更少的代码耦合
* a. 子类自动继承父类所有的公有成员
* b. 子类可以访问父类的保护成员
* - 继承破坏了封装性
*/
/*
* 2. 动态绑定
* a. 继承在编译时绑定
* b. 组合可以在编译时绑定,也可以在运行时绑定
*/
class OutdoorActivityManager : public ActivityManager {...}
class IndoorActivityManager : public ActivityManager {...}
/*
* 3. 灵活的代码结构
*
* Dog ActivityManager
*
* BullDog OutdoorActivityManager
* ShepherdDog IndoorActivityManager
* ... ...
*/
// 组合的例子:只从纯虚类继承
class ActivityManager {
void eatBiscuit() { ... }
};
class Dog {
...
virtual void eatBiscuit() = 0;
};
class BullDog : public Dog {
ActivityManager* pActMngr;
...
void eatBiscuit() { pActMngr->eatBiscuit(); }
};
class ShepherdDog : public Dog {
ActivityManager* pActMngr;
...
void eatBiscuit() { pActMngr->eatBiscuit(); }
};