2. C++ 继承

1. 简介

继承 ,表示两个类的关系,即通过已存在的类来创建一个新的类。其中已存在的类称为基类,新创建的类则称为派生类。

注: C++的继承类似于C语言中的结构体与结构体变量的关系:在C语言中,首先建立结构体以及其内部的结构体成员,然后以此结构体作为数据类型定义若干个结构体变量。如此一来,这些结构体变量就都包含了构建的结构体成员。


基类&派生类

由上面的介绍,基本了解了基类与派生类的概念以及关系。其中派生类可以源于一个或多个基类,即可以继承多个基类。形式如下:

// class [派生类名]:[继承类型] [基类名]
class child-class: access-specifier parent-class 
{
 //<派生类体>
}

child-class表示派生类名;parent-class表示基类名; access-specifier表示继承类型,即public、protected和private三种之中的一个,若未声明,默认private类型。

//E.g. 拷贝https://www.runoob.com/cplusplus/cpp-inheritance.html
#include <iostream>
 
using namespace std;
 
// 基类
class Shape 
{
   public:
      void setWidth(int w)
      {
         width = w;
      }
      void setHeight(int h)
      {
         height = h;
      }
   protected:
      int width;
      int height;
};
 
// 派生类
class Rectangle: public Shape
{
   public:
      int getArea()
      { 
         return (width * height); 
      }
};


int main(void)
{
   Rectangle Rect;
 
   Rect.setWidth(5);
   Rect.setHeight(7);
 
   // 输出对象的面积
   cout << "Total area: " << Rect.getArea() << endl;
 
   return 0;
}

输出:

Total area: 35

访问权限与继承

基类也可以通过将成员权限声明为private,来保护成员不被派生类直接访问。列举一下访问权限关系:

访问publicprotectedprivate
同一个类yesyesyes
派生类yesyesno
外部的类yesnono

一个派生类继承了所有的基类方法,但下列情况除外:

  • 基类的构造函数、析构函数和拷贝构造函数。
  • 基类的重载运算符。
  • 基类的友元函数。

继承类型

当一个类派生自基类,该基类可以被继承为 public、protected 或 private 几种类型。继承类型是通过上面讲解的访问修饰符 access-specifier 来指定的。

在实际编程中很少用到protected 或 private 继承,通常使用 public 继承。当使用不同类型的继承时,遵循以下几个规则:

公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。


多继承

在上面也讲到一个类可以派生自多个基类,即多继承。派生类具备了所继承的多个基类的特性。
语法:

class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
{
//<派生类类体>
};

看一下实际编程的使用:

#include <iostream>
 
using namespace std;
 
// 基类 Shape
class Shape 
{
   public:
      void setWidth(int w)
      {
         width = w;
      }
      void setHeight(int h)
      {
         height = h;
      }
   protected:
      int width;
      int height;
};
 
// 基类 PaintCost
class PaintCost 
{
   public:
      int getCost(int area)
      {
         return area * 70;
      }
};
 
// 派生类
class Rectangle: public Shape, public PaintCost
{
   public:
      int getArea()
      { 
         return (width * height); 
      }
};
 
int main(void)
{
   Rectangle Rect;
   int area;
 
   Rect.setWidth(5);
   Rect.setHeight(7);
 
   area = Rect.getArea();
   
   // 输出对象的面积
   cout << "Total area: " << Rect.getArea() << endl;
 
   // 输出总花费
   cout << "Total paint cost: $" << Rect.getCost(area) << endl;
 
   return 0;
}

输出:

Total area: 35
Total paint cost: $2450

小结: 在这篇实例中可以发现,Rectangle类继承了 Shape类和PaintCost类,等同于Rectangle其内部包含了Shape类的width、height成员、setWidth(int w)、setHeight(int h)方法 和 PaintCost 中的getArea方法以及自己定义的getArea方法。相当于用较少的代码实现了一个集成多个父类特性的派生类。


总结

  1. 继承可以理解为编程中的偷懒技巧,例如当我要定义一个长方形对象,一个正方形对象,一个圆形对象,那么我们就将这三个对象的共同特性提取出来形成基类,不同的特性则放到自己的类中实现。从而使代码更简洁,同时方便后期代码的增加与维护。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拂去尘世尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值