猫猫哥

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
//############################################################################
/*
 * 代码复用: 继承 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(); }
};
posted on 2018-12-25 22:51  猫猫哥  阅读(453)  评论(0编辑  收藏  举报