C++ 类继承
当然可以!既然你是 C++ 初学者,有 C 的基础,我们就用你能熟悉的方式来讲清楚 C++ 的 类继承(inheritance),再配一个简单易懂的例子。
🧠 什么是类继承?
类继承 是 C++ 的一个重要特性,让你可以基于一个“已有的类”(父类或基类)去“扩展”出新的类(子类或派生类),复用已有代码并添加新功能。
你可以理解为:
子类 = 父类 + 自己的新东西
📦 通俗类比:
想象你有一个“交通工具”类(Vehicle):
- 所有交通工具都有 品牌、速度、移动() 方法。
你又想创建“汽车类”(Car)和“自行车类”(Bike),它们跟交通工具很像,但各自又有新特性,比如:
- 汽车有油箱容量
- 自行车有人力驱动方式
你没必要复制一份“品牌”、“速度”的代码,只要继承自交通工具就行。
📘 示例代码:通俗易懂的交通工具案例
#include <iostream>
using namespace std;// 父类(基类)
class Vehicle {
public:string brand;int speed;void move() {cout << brand << " 正在以 " << speed << " km/h 的速度移动。" << endl;}
};// 子类(派生类)
class Car : public Vehicle {
public:int fuel; // 汽油量void showFuel() {cout << "当前油量是 " << fuel << " 升。" << endl;}
};int main() {Car myCar;myCar.brand = "Toyota";myCar.speed = 120;myCar.fuel = 40;myCar.move(); // 调用继承来的函数myCar.showFuel(); // 调用子类自己的函数return 0;
}
🔍 输出结果:
Toyota 正在以 120 km/h 的速度移动。
当前油量是 40 升。
🧩 学到了什么:
- 子类
Car
继承了Vehicle
的成员(brand
、speed
、move()
) - 子类可以添加自己的成员变量(如
fuel
)和方法(如showFuel()
) - 可以像用普通类一样使用继承后的类
🎓 小贴士(你需要知道的):
关键字 | 作用 |
---|---|
class A | 定义一个类 A |
class B : public A | B 是 A 的子类,继承 A 的 公共成员 |
public | 表示公开继承,是最常用的继承方式 |
protected | 子类能访问,外部不能访问 |
private | 子类和外部都不能访问 |
✅ 总结一句话:
继承 = 复用已有类的功能 + 扩展自己的新能力
它让你可以用“父类打基础,子类加功能”的方式组织代码,减少重复,提高可维护性。
你想接着学「多态(virtual 函数)」、「构造函数如何继承」、「私有继承和保护继承的区别」吗?还是先巩固基本继承?
太好了!那我们就一步一步升级学习 C++ 继承的更多特性。先从你现在的基础出发,我们继续讲讲:
✅ 1. 构造函数在继承中的工作方式
我们先继续用前面的交通工具例子。
🔧 子类如何构造父类的部分?
class Vehicle {
public:Vehicle(string b, int s) {brand = b;speed = s;}void move() {cout << brand << " 正在以 " << speed << " km/h 的速度移动。" << endl;}protected:string brand;int speed;
};class Car : public Vehicle {
public:Car(string b, int s, int f) : Vehicle(b, s) {fuel = f;}void showFuel() {cout << "当前油量是 " << fuel << " 升。" << endl;}private:int fuel;
};
📝 说明:
Car
的构造函数通过: Vehicle(b, s)
先调用父类构造函数。- 这是必须的,因为父类
Vehicle
没有默认构造函数(自己写了带参数的)。
✅ 2. 多态:让父类指针/引用调用子类函数(virtual)
这是 C++ 的精髓之一!叫做 多态(polymorphism)。
🌟 举个经典例子:
class Vehicle {
public:virtual void move() { // 注意 virtualcout << "交通工具在移动。" << endl;}
};class Car : public Vehicle {
public:void move() override { // 重写父类的 movecout << "汽车在公路上快速移动!" << endl;}
};
👇 使用:
int main() {Vehicle* v; // 父类指针Car myCar;v = &myCar;v->move(); // 实际调用的是 Car 的 move()(多态)
}
✅ 输出:
汽车在公路上快速移动!
🧠 为什么要这样做?
你可以写很多子类(Car、Bike、Train…),但都统一用 Vehicle*
来管理它们。
✅ 多态 = 父类指针/引用调用子类的重写方法,前提是函数要加上
virtual
。
✅ 3. protected 访问权限
你已经熟悉 public
和 private
,那 protected
是介于两者之间的访问权限:
protected
:子类可以访问,外部不可以访问
class Vehicle {
protected:string brand;
};class Car : public Vehicle {
public:void showBrand() {cout << "品牌是 " << brand << endl; // ✅ 可以访问}
};int main() {Car c;// c.brand = "Toyota"; ❌ 错误:外部不能访问 protected
}
✅ 总结升级版:
特性 | 说明 |
---|---|
virtual | 实现多态:让子类函数替代父类函数调用 |
override | 明确声明是重写父类虚函数 |
protected | 子类可以访问,外部不行 |
构造函数初始化 | 子类构造函数可通过 : Base(...) 初始化父类 |
✅ 推荐练习(可选):
你可以练习写一个小系统,例如:
- 基类
Animal
有speak()
方法 - 派生类
Dog
、Cat
重写speak()
- 写一个
Animal*
的数组遍历并调用speak()
,体验多态
如果你需要我给你写这个完整的练习示例,或者加上文件分离(.h/.cpp
)方式,我也可以继续帮你整理!继续吗?