继承
请注意,本文尚未完成!您可以通过编辑此文档页面来提供帮助。
在本课程中,您将学习如何使用继承来通过构建类层次结构并防止冗余代码来共享其他类的属性和特性。
动机
在创建模拟现实世界元素的数据结构时,我们经常遇到两种此类结构共享共同属性的情况。例如,如果我们制作一个包含飞机 ✈ 和汽车 🚗 的车辆游戏,我们将创建两个这样的结构
struct Car
{
std::string brand;
std::string model;
int production_year;
bool is_cabrio;
};
struct Airplane
{
std::string brand;
std::string model;
int production_year;
int number_of_engines;
std::string airlines_name;
};
注意突出显示的行。经过简要分析,我们可以发现这两种结构共享这些共同属性
- 品牌
- 型号
- 生产年份
在本课程的后面,我们将使用继承将这两个结构与一个共同的基础结构连接起来。
基础结构
现在我们指出了共同属性,我们可以创建只包含这些字段的结构
struct Vehicle
{
std::string brand;
std::string model;
int production_year;
};
注意名称 - Vehicle
。它是一个描述车辆一般形式的结构。创建此类结构的实例意义不大
// prism-push-types:Vehicle
Vehicle vehicle;
上面的代码不会导致编译错误。将来我们将学习如何通过使用私有构造函数来防止其他人创建此类对象的实例。
取而代之的是,我们将使用 Vehicle
来制作 Car
和 Airplane
结构,以便它们继承其属性。
派生结构
为了使用继承创建派生结构,我们必须在冒号后放置基础结构名称
struct Car : Vehicle
{
bool is_cabrio;
};
struct Airplane : Vehicle
{
int number_of_engines;
std::string airlines_name;
}
查看完整代码
// prism-push-types:Vehicle,Car,Airplane
#include <string>
struct Vehicle
{
std::string brand;
std::string model;
int production_year;
};
struct Car : Vehicle
{
bool is_cabrio;
};
struct Airplane : Vehicle
{
int number_of_engines;
std::string airlines_name;
};
int main()
{
// empty for now
}
我们必须将 Vehicle
定义放在派生结构定义之前。
用法
上面的图表显示,从 Vehicle
继承的属性都在 Car
和 Airplane
结构中。
正因为如此,当我们在代码中创建汽车时,我们可以使用 brand
、model
和 production_year
字段,就像它们直接在 Car
结构中一样
// prism-push-types:Car
Car ford;
ford.brand = "Ford";
ford.model = "Fiesta";
ford.production_year = 2010;
ford.is_cabrio = false;
飞机也一样
// prism-push-types:Airplane
Airplane boeing;
boeing.brand = "Boeing";
boeing.model = "737";
boeing.production_year = 2010;
boeing.number_of_engines = 2;
boeing.airlines_name = "Air Canada";
查看完整代码
// prism-push-types:Vehicle,Car,Airplane
#include <iostream>
#include <string>
struct Vehicle
{
std::string brand;
std::string model;
int production_year;
};
struct Car : Vehicle
{
bool is_cabrio;
};
struct Airplane : Vehicle
{
int number_of_engines;
std::string airlines_name;
};
int main()
{
Car ford;
ford.brand = "Ford";
ford.model = "Fiesta";
ford.production_year = 2010;
ford.is_cabrio = false;
Airplane boeing;
boeing.brand = "Boeing";
boeing.model = "737";
boeing.production_year = 2010;
boeing.number_of_engines = 2;
boeing.airlines_name = "Air Canada";
std::cout << ford.brand << '\n'; // "Ford"
std::cout << boeing.brand << '\n'; // "Boeing"
}
继承方法
就像成员变量一样,方法也同样被继承。让我们向 Vehicle
类添加 complete_name()
方法,该方法将返回由 brand
和 model
组成的名称
struct Vehicle
{
// ...
std::string complete_name()
{
return brand + " " + model;
}
};
现在我们可以对 Car
实例使用此方法
// prism-push-types:Car
Car ford;
ford.brand = "Ford";
ford.model = "Fiesta";
std::cout << ford.complete_name(); // "Ford Fiesta"
查看完整代码
// prism-push-types:Vehicle,Car,Airplane
#include <iostream>
#include <string>
struct Vehicle
{
std::string brand;
std::string model;
int production_year;
std::string complete_name()
{
return brand + " " + model;
}
};
struct Car : Vehicle
{
bool is_cabrio;
};
struct Airplane : Vehicle
{
int number_of_engines;
std::string airlines_name;
};
int main()
{
Car ford;
ford.brand = "Ford";
ford.model = "Fiesta";
ford.production_year = 2010;
ford.is_cabrio = false;
Airplane boeing;
boeing.brand = "Boeing";
boeing.model = "737";
boeing.production_year = 2010;
boeing.number_of_engines = 2;
boeing.airlines_name = "Air Canada";
std::cout << ford.complete_name() << '\n'; // "Ford Fiesta"
std::cout << boeing.complete_name() << '\n'; // "Boeing 737"
}