C++补充基础小知识:什么是接口类 和 抽象类?为什么要继承?
接口类 和 抽象类,确实有很多人容易混淆,今天我就一次性帮你彻底搞懂这两个概念,以及为什么要继承!
🌳 1️⃣ 什么是接口类?什么是抽象类?
分类 | 接口类 (Interface) | 抽象类 (Abstract Class) |
---|---|---|
定义 | 只包含纯虚函数(没有实现) | 至少包含一个纯虚函数,可以有部分实现 |
目的 | 只定义规范,不实现逻辑 | 定义规范 + 可以提供部分实现 |
成员变量 | 没有(通常不应该有) | 可以有成员变量和普通成员函数 |
典型例子 | class IShape { virtual void draw() = 0; }; | class Shape { virtual void draw() = 0; void move() {}; }; |
是否必须继承 | ✅ 必须继承并实现 | ✅ 必须继承并实现纯虚函数 |
特点 | 类似于纯接口 | 类似于半成品,可以扩展 |
✅ 举例 1:接口类
// 接口类:完全定义规范,不写实现
class IShape {
public:virtual void draw() = 0; // 纯虚函数virtual ~IShape() {} // 虚析构
};
你必须继承它才能用:
class Circle : public IShape {
public:void draw() override { qDebug() << "Draw Circle"; }
};
✅ 举例 2:抽象类
class Shape {
public:virtual void draw() = 0; // 抽象函数void move() { qDebug() << "Move shape"; } // 已实现
};
抽象类可以提供一部分公共实现(如 move()
),子类继承后可以直接用。
🏗️ 2️⃣ 为什么必须继承它们?
因为:
-
接口类和抽象类只是“模板”/“规范”,没有完整实现,不能直接创建对象。
-
编译器禁止实例化(new)它们。
举例:
IShape shape; // ❌ 错误,不能创建接口类对象
Shape shape; // ❌ 错误,不能创建抽象类对象
你必须 继承 + 实现纯虚函数,才能使用:
class Circle : public IShape {void draw() override { qDebug() << "Draw Circle"; }
};Circle c; // ✅ OK
🧭 3️⃣ 接口类 vs. 抽象类 - 什么时候用?
你要做什么? | 选哪个? | 举例 |
---|---|---|
定义一个“规范”,子类必须遵循,且不需要公共代码 | 接口类 | IDrawable , ISerializable |
定义一个“规范”,但有些通用代码可以共享 | 抽象类 | QWidget , QThread (部分实现) |
已有完整实现,不需要额外规范 | 具体类 | QTimer , QList |
🏆 4️⃣ 总结
✅ 接口类 = 纯虚函数集合,只定义规范,不提供实现。
✅ 抽象类 = 至少有一个纯虚函数,可以提供部分实现。
✅ 使用它们时,必须 继承并实现所有纯虚函数 才能创建对象。
✅ 目的是:面向接口编程,让代码更灵活、可扩展。
🎓 5️⃣ 举个生活中的例子
角色 | 接口类 | 抽象类 | 具体类 |
---|---|---|---|
概念 | 会飞的东西(不能直接用) | 飞行工具(有一些基本结构,但不能直接买) | 一架飞机(可以买来用) |
类比 | IFlyable | Aircraft | Boeing737 |
特点 | 只定义规范 | 有些实现 | 全部实现 |
代码 | virtual void fly() = 0; | virtual void fly() = 0; void refuel() {} | void fly() override {} |
如果你有实际代码场景(比如某个类不知道该不该继承),发给我,我们一起看看! 🚀