在太平洋上看的一个高手的文章,没看懂,大侠解释一下
(2)若在逻辑上A 是B 的“一部分”(a part of),则不允许B 继承A 的功能,而是要用A和其它东西组合出B。例如眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head 应该由类Eye、Nose、Mouth、Ear 组合而成,不是派生而成。示例程序如下:
- C/C++ code
class Eye{public:void Look(void);};class Nose{public:void Smell(void);};class Mouth{public:void Eat(void);};class Ear{public:void Listen(void);};// 正确的设计,冗长的程序class Head{public:void Look(void) { m_eye.Look(); }void Smell(void) { m_nose.Smell(); }void Eat(void) { m_mouth.Eat(); }void Listen(void) { m_ear.Listen(); }private:Eye m_eye;Nose m_nose;Mouth m_mouth;Ear m_ear;};如果允许Head 从Eye、Nose、Mouth、Ear 派生而成,那么Head 将自动具有Look、Smell、Eat、Listen 这些功能:
// 错误的设计
class Head : public Eye, public Nose, public Mouth, public Ear
{
};
上述程序十分简短并且运行正确,但是这种设计却是错误的。很多程序员经不起“继承”的诱惑而犯下设计错误。
为什么上面的那种方式好,而下面的方式不好?
[解决办法]
C++ primer上面好像有这个的例子,一个是继承,一个是组合。
如果使用继承从道理上说不清楚的。可以说子类是父类,但是能说head是eye吗?但是head包含了eye
推荐使用组合。
[解决办法]
逻辑上明显是前者好,另外
比如眼睛有一个属性color,head继承了这个属性变成head::color,格式不符合实际的语义
而如果其它类如mouth又有color属性的话会更麻烦
[解决办法]
继承是属于IsA的情况,明显Head与Nose,Eye是平等的关系, 是属于HasA,所以使用嵌套
[解决办法]
就是is a 和has a的问题
[解决办法]
继承一定要是is a关系.