C++中继承与组合的区别详细解析

 更新时间:2020年4月25日 17:44  点击:1448

C++的“继承”特性可以提高程序的可复用性。正因为“继承”太有用、太容易用,才要防止乱用“继承”。我们要给“继承”立一些使用规则:

一、如果类A 和类B 毫不相关,不可以为了使B 的功能更多些而让B 继承A 的功能。

不要觉得“不吃白不吃”,让一个好端端的健壮青年无缘无故地吃人参补身体。

二、如果类B 有必要使用A 的功能,则要分两种情况考虑:

(1)若在逻辑上B 是A 的“一种”(a kind of ),则允许B 继承A 的功能。如男人(Man)是人(Human)的一种,男孩(Boy)是男人的一种。那么类Man 可以从类Human 派生,类Boy 可以从类Man 派生。示例程序如下:

复制代码 代码如下:

class Human
{
  …
};
class Man : public Human
{
  …
};
class Boy : public Man
{
  …
};

(2)若在逻辑上A 是B 的“一部分”(a part of),则不允许B 继承A 的功能,而是要用A和其它东西组合出B。例如眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head 应该由类Eye、Nose、Mouth、Ear 组合而成,不是派生而成。示例程序如下:

复制代码 代码如下:

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
{
};


上述程序十分简短并且运行正确,但是这种设计却是错误的。这就开头所说的很多程序员经不起“继承”的诱惑而犯下设计错误。

[!--infotagslink--]

相关文章

  • 原生Javascript实现继承方式及其优缺点详解

    JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一,那么这篇文章主要给大家介绍了关于原生Javascript实现继承方式及其优缺点的相关资料,需要的朋友可以参考下...2021-07-21
  • php构造方法中析构方法在继承中的表现

    这篇文章主要为大家详细介绍了php构造方法中析构方法在继承中的表现,感兴趣的小伙伴们可以参考一下...2016-04-15
  • 深入分析c# 继承

    这篇文章主要介绍了c# 继承的相关资料,文中讲解的非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-11-03
  • javascript中的3种继承实现方法

    这篇文章主要介绍了javascript中的3种继承实现方法,包括使用Object.create实现类式继承、使用utilities工具包自带的util.inherites、使用extends关键字,非常的实用,希望对大家了解javascript继承能够有所帮助...2016-01-30
  • 理解js对象继承的N种模式

    这篇文章主要为大家举例介绍了js对象继承的几种模式,内容很全面,感兴趣的小伙伴们可以参考一下...2016-01-26
  • js继承的6种方式详解

    这篇文章主要给大家介绍了关于js继承的6种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-06
  • C#实现生成所有不重复的组合功能示例

    这篇文章主要介绍了C#实现生成所有不重复的组合功能,涉及C#数学运算中组合数运算的相关原理应用操作技巧,需要的朋友可以参考下...2020-06-25
  • js中实现继承的五种方法

    这篇文章主要介绍了js中实现继承的五种方法,帮助大家更好的理解和使用JavaScript,感兴趣的朋友可以了解下...2021-01-26
  • Spring Cloud中使用Feign,@RequestBody无法继承的解决方案

    这篇文章主要介绍了Spring Cloud中使用Feign,@RequestBody无法继承的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-22
  • 简单理解JavaScript中的封装与继承特性

    这篇文章主要介绍了JavaScript中的封装与继承特性,封装与继承是基于对象编程概念中的基本特性,需要的朋友可以参考下...2016-03-22
  • ES6新特性之类(Class)和继承(Extends)相关概念与用法分析

    这篇文章主要介绍了ES6新特性之类(Class)和继承(Extends)相关概念与用法,结合实例形式较为详细的分析了ES6中类(Class)和继承(Extends)的基本概念、语法、使用方法与注意事项,需要的朋友可以参考下...2017-05-27
  • 谈一谈javascript中继承的多种方式

    本文就和大家谈一谈javascript中的继承,什么是继承,继承的作用,以及js继承的实现代码,感兴趣的小伙伴们可以参考一下...2016-02-21
  • 浅谈C# 类的继承

    本文主要介绍了C# 类的继承相关知识。具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
  • C#查找字符串所有排列组合的方法

    这篇文章主要介绍了C#查找字符串所有排列组合的方法,涉及C#字符串操作的相关技巧,非常具有实用价值,需要的朋友可以参考下...2020-06-25
  • 详解JavaScript基于面向对象之继承实例

    这篇文章主要介绍了JavaScript基于面向对象之继承实例,需要的朋友可以参考下...2015-12-18
  • js实现简单排列组合的方法

    这篇文章主要介绍了js实现简单排列组合的方法,可实现数学上排列组合算法功能,涉及JavaScript数组与字符串操作技巧,需要的朋友可以参考下...2016-01-29
  • C++设计类不能被继承的方法实例讲解

    在Java 中定义了关键字final,被final修饰的类不能被继承,C++中如何实现,下面我们来看一个例子...2020-04-25
  • C#中实现多继承的方法

    这篇文章主要介绍了C#中实现多继承的方法,本文通过给接口添加扩展的方法实现了C#的多继承,需要的朋友可以参考下...2020-06-25
  • 夯基础之手撕javascript继承详解

    这篇文章主要给大家介绍了关于手撕javascript继承的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-10
  • C#实现排列组合算法完整实例

    这篇文章主要介绍了C#实现排列组合算法的完整实例,文中实例主要展示了排列循环方法和排列堆栈方法,需要的朋友可以参考下...2020-06-25