智慧屏|也许你需要这篇文章来理解C++中的继承

智慧屏|也许你需要这篇文章来理解C++中的继承

文章图片

智慧屏|也许你需要这篇文章来理解C++中的继承

文章图片

智慧屏|也许你需要这篇文章来理解C++中的继承

文章图片

智慧屏|也许你需要这篇文章来理解C++中的继承

文章图片

智慧屏|也许你需要这篇文章来理解C++中的继承

文章图片

智慧屏|也许你需要这篇文章来理解C++中的继承

文章图片

智慧屏|也许你需要这篇文章来理解C++中的继承

文章图片

智慧屏|也许你需要这篇文章来理解C++中的继承

文章图片

智慧屏|也许你需要这篇文章来理解C++中的继承

文章图片

智慧屏|也许你需要这篇文章来理解C++中的继承

文章图片


一个类从另一个类派生属性和特性的能力称为继承 。 继承是面向对象编程的最重要功能之一 。
子类:从另一个类继承属性的类称为子类或派生类 。
超类:其属性被子类继承的类称为基类或超类 。
本文分为以下子主题:

  1. 为什么以及何时使用继承?
  2. 继承方式
  3. 继承类型
一.为什么以及何时使用继承:
考虑一组车辆 。 您需要为公交车 , 汽车和卡车创建类 。 对于这三个类 , 方法fuelAmount() , capacity() , applyBrakes()都是相同的 。 如果创建这些类以避免继承 , 则必须在三个类的每一个中编写所有这些函数 , 如下图所示(图片为了好看有些东西就用英文代替了 , 您应该看得懂):

您可以清楚地看到上述过程导致相同代码重复3次 。 这增加了错误和数据冗余的机会 。 为了避免这种情况 , 将使用继承 。 如果我们创建一个Vehicle类 , 并在其中编写这三个函数 , 并从Vehicle类继承其余的类 , 那么我们可以简单地避免数据重复并提高可重用性 。 请看下图 , 其中三个类是从车辆类 继承的:使用继承 , 我们必须只编写函数一次而不是编写三次函数 , 因为我们已经从基类(车辆)继承了其余三个类 。

在C ++中实现继承:
要创建从基类继承的子类 , 我们必须遵循以下语法:

在这里 , subclass_name是子类的名称 , access_mode是您要继承该子类的模式 , 例如:public , private等 , 而base_class_name是您要从其继承子类的基类的名称 。。
注意:派生类不会继承对私有数据成员的访问 。 但是 , 它确实继承了完整的父对象 , 该对象包含该类声明的所有私有成员 。

输出:Child ID是7 Parent ID是91
在上面的程序中 , “ Child”类是从“ Parent”类公开继承的 , 因此“ Parent”类的公共数据成员也将由“ Child”类继承 。
二.继承方式:
  1. 公共模式:如果我们从公共基类派生子类 。 然后 , 基类的公共成员将在派生类中成为公共成员 , 基类的受保护成员将在派生类中成为受保护成员 。
  2. 保护模式:如果我们从保护的基类派生一个子类 。 然后 , 基类的公共成员和受保护的成员都将在派生类中受到保护 。
  3. 私有模式:如果我们从私有基类派生子类 。 然后 , 基类的公共成员和受保护的成员都将成为派生类中的私有成员 。
注意:无法直接在派生类中访问基类中的私有成员 , 而可以直接访问受保护的成员 。 例如 , 在下面的示例中 , 类B , C和D都包含变量x , y和z 。 这只是访问的问题 。

三.C ++中的继承类型:
1.单一继承:在单一继承中 , 一个类只能从一个类继承 。 即一个子类只能被一个基类继承 。

Derived class:衍生类别
语法:

2.多重继承:多重继承是C ++的一项功能 , 其中一个类可以从多个类中继承 。 即一个子类是从一个以上的基类继承的 。

语法:

在此 , 基类的数量将以逗号(' , ')分隔 , 并且必须为每个基类指定访问模式 。

3.多级继承:在这种继承类型中 , 从另一个派生类创建一个派生类 。


4.层次继承:在这种继承中 , 一个基类继承了多个子类 。 即 , 从一个基类创建一个以上的派生类 。


5.混合(虚拟)继承:混合继承是通过组合多种类型的继承来实现的 。 例如:组合层次继承和多重继承 。
下图显示了层次继承和多重继承的组合:


6.混合继承的一种特殊情况:多路径继承:
具有两个基类且这两个基类具有一个公共基类的派生类称为多路径继承 。 这种继承会产生歧义

您可以尝试以下程序:

在上面的示例中 , ClassB和ClassC都继承了ClassA , 它们都具有ClassA的单个副本 。 但是 , ClassD继承了ClassB和ClassC , 因此ClassD具有ClassA的两个副本 , 一个副本来自ClassB , 另一个副本来自ClassC 。
如果我们需要通过ClassD的对象访问ClassA的数据成员a , 则必须指定从中访问a的路径 , 无论它是来自ClassB还是ClassC , 编译器都无法区分ClassA的两个副本在ClassD中 。
有两种方法可以避免这种歧义:
  1. 使用范围解析运算符
  2. 使用虚拟基类
使用范围解析运算符避免歧义:
使用范围解析运算符 , 我们可以手动指定从中访问数据成员a的路径 , 如上例中的语句3和4所示
使用虚拟基类避免歧义:

根据上面的示例 , ClassD只有ClassA的一个副本 , 因此 , 语句4将覆盖语句3中给出的a的值 。
【智慧屏|也许你需要这篇文章来理解C++中的继承】


    推荐阅读