C++進階--程式碼複用 繼承vs組合
阿新 • • 發佈:2018-12-25
//############################################################################ /* * 程式碼複用: 繼承 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(); } };