45.md 6.1 KB
Newer Older
W
wizardforcel 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# C++ 继承

> 原文: [https://www.programiz.com/cpp-programming/inheritance](https://www.programiz.com/cpp-programming/inheritance)

#### 在本文中,您将学习有关 C++ 中继承的所有知识。 更具体地说,继承是什么以及通过示例实现继承的不同方法。

继承是 C++ 中面向对象编程的主要功能之一。 它允许用户从现有的类(基类)创建一个新的[](/cpp-programming/object-class "C++ class")(派生类)。

派生类继承了基类的所有功能,并且可以拥有自己的其他功能。

* * *

## 为什么要使用继承?

假设您在游戏中需要三个角色-**数学老师****足球运动员****商人**

由于所有角色都是人,因此他们可以走路和说话。 但是,他们也有一些特殊技能。 数学老师可以**教数学**,足球运动员可以**踢足球**,商人可以**经营企业**

W
wizardforcel 已提交
19
您可以单独创建三个可以走路,说话和执行其特殊技能的类,如下图所示。
W
wizardforcel 已提交
20 21 22 23 24

![Solving a problem without inheritance in C++](img/f8a8ee6ec7e2d237bc937d6925ca1938.png "Without inheritance")

在每个类中,您将为每个角色复制相同的步行和交谈代码。

W
wizardforcel 已提交
25
如果要添加新函数`eat`,则需要为每个字符实现相同的代码。 这很容易导致出错(复制时)和重复代码。
W
wizardforcel 已提交
26

W
wizardforcel 已提交
27
如果我们有一个`Person`类,它具有基本的功能,例如说话,走路,吃饭,睡觉,并根据我们的角色向这些功能添加特殊技能,那就容易得多。 这是使用继承完成的。
W
wizardforcel 已提交
28 29 30

![Solving a problem with inheritance in C++](img/011ebcb014c7bf6647136e65638726ae.png "With inheritance")

W
wizardforcel 已提交
31
使用继承,现在您不必为每个类实现相同的代码。 您只需要**继承它们即可**
W
wizardforcel 已提交
32

W
wizardforcel 已提交
33
因此,对于数学老师(派生类),您可以继承`Person`(基类)的所有函数并添加新函数`TeachMaths`。 同样,对于足球运动员,您继承了`Person`的所有函数并添加了新函数`PlayFootball`,依此类推。
W
wizardforcel 已提交
34 35 36

这使您的代码更简洁,易于理解和可扩展。

W
wizardforcel 已提交
37
**重要的是要记住**:在处理继承时,每个派生类都应满足“**是**”基类的条件。 在上面的示例中,数学老师**是**人,足球先生**是**人。 您不能拥有:商人**是**企业。
W
wizardforcel 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

* * *

## C++ 编程中继承的实现

```cpp
class Person 
{
  ... .. ...
};

class MathsTeacher : public Person 
{
  ... .. ...
};

class Footballer : public Person
{
  .... .. ...
};

```

W
wizardforcel 已提交
61
在以上示例中,类别`Person`是基类,类别`MathsTeacher``Footballer`是从`Person`派生的。
W
wizardforcel 已提交
62

W
wizardforcel 已提交
63
派生的类与类的声明一起显示,后跟冒号,关键字`public`和派生该类的基类的名称。
W
wizardforcel 已提交
64

W
wizardforcel 已提交
65
由于`MathsTeacher``Footballer`源自`Person`,因此可以从中访问`Person`的所有数据成员和成员函数。
W
wizardforcel 已提交
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143

* * *

## 示例:C++ 编程中的继承

使用继承概念创建游戏角色。

```cpp
#include <iostream>
using namespace std;

class Person
{
     public:
        string profession;
        int age;

        Person(): profession("unemployed"), age(16) { }
        void display()
        {
             cout << "My profession is: " << profession << endl;
             cout << "My age is: " << age << endl;
             walk();
             talk();
        }
        void walk() { cout << "I can walk." << endl; }
        void talk() { cout << "I can talk." << endl; }
};

// MathsTeacher class is derived from base class Person.
class MathsTeacher : public Person
{
    public:
       void teachMaths() { cout << "I can teach Maths." << endl; }
};

// Footballer class is derived from base class Person.
class Footballer : public Person
{
    public:
       void playFootball() { cout << "I can play Football." << endl; }
};

int main()
{
     MathsTeacher teacher;
     teacher.profession = "Teacher";
     teacher.age = 23;
     teacher.display();
     teacher.teachMaths();

     Footballer footballer;
     footballer.profession = "Footballer";
     footballer.age = 19;
     footballer.display();
     footballer.playFootball();

     return 0;
}
```

**输出**

```cpp
My profession is: Teacher
My age is: 23
I can walk.
I can talk.
I can teach Maths.
My profession is: Footballer
My age is: 19
I can walk.
I can talk.
I can play Football.
```

在此程序中,`Person`是基类,而`MathsTeacher``Footballer`是从`Person`派生的。

W
wizardforcel 已提交
144
`Person`类具有两个数据成员 - `profession``age`。 它还具有两个成员函数-`walk()``talk()`
W
wizardforcel 已提交
145

W
wizardforcel 已提交
146
`MathsTeacher``Footballer`都可以访问`Person`的所有数据成员和成员函数。
W
wizardforcel 已提交
147

W
wizardforcel 已提交
148
但是,`MathsTeacher``Footballer`也具有自己的成员函数:分别为`teachMaths()``playFootball()`。 这些函数只能由自己的类访问。
W
wizardforcel 已提交
149

W
wizardforcel 已提交
150
`main()`函数中,创建了一个新的`MathsTeacher`对象`Teacher`
W
wizardforcel 已提交
151

W
wizardforcel 已提交
152
由于可以访问`Person`的数据成员,因此设置了`Teacher``profession``age`。 使用在`Person`类中定义的`display()`函数显示此数据。 此外,将调用`MathsTeacher`类中定义的`teachMaths()`函数。
W
wizardforcel 已提交
153

W
wizardforcel 已提交
154
同样,还将创建一个新的`Footballer`对象`footballer`。 它也可以访问`Person`的数据成员,这可以通过调用`display()`函数来显示。 然后,只有足球运动员才能使用的`playFootball()`函数被调用。
W
wizardforcel 已提交
155 156 157 158 159 160 161 162 163

* * *

### 继承中的访问说明符

从基类创建派生类时,可以使用不同的访问说明符来继承基类的数据成员。

这些可以是公共的,受保护的或私有的。

W
wizardforcel 已提交
164
在以上示例中,基类`Person`已由`MathsTeacher``Footballer`公开继承。
W
wizardforcel 已提交
165

W
wizardforcel 已提交
166
了解有关 C++ 中的[公共,保护和私有继承的更多信息](/cpp-programming/public-protected-private-inheritance "Public, Protected and Private inheritance in C++")
W
wizardforcel 已提交
167 168 169

* * *

W
wizardforcel 已提交
170
### 继承中的成员函数覆盖
W
wizardforcel 已提交
171 172 173 174 175 176 177

假设基类和派生类的成员函数具有相同的名称和参数。

如果创建派生类的对象并尝试访问该成员函数,则仅调用派生类中的成员函数。

派生类的成员函数将覆盖基类的成员函数。

W
wizardforcel 已提交
178
了解有关 C++ 中的[函数覆盖的更多信息](/cpp-programming/function-overriding "C++ function overriding")