Dart 类与继承:extends 与 implements
在 Dart 语言中,处理类与类的关系时,最常遇到两个关键字:extends(继承)和 implements(实现)。它们决定了你的代码如何复用、如何扩展。下面直接拆解使用场景与具体步骤。
extends 用于复用父类的具体实现。子类自动获得父类的非私有属性和方法,并可重写它们。Dart 只允许单继承。
implements 用于强制约定接口行为。子类必须完整重写被 implements 的类或接口中的所有公开成员。Dart 允许同时 implements 多个类。
阶段一:使用 extends 扩展已有功能
当两个类属于“同类事物的不同细分”(例如:动物 和 狗),且你需要复用大部分已有逻辑时,按以下步骤操作:
- 创建 基础父类。使用
class关键字声明父类,并在内部定义通用属性与方法。 - 声明 子类继承。在类名后使用
extends关键字紧跟父类名,语法格式固定为class 子类名 extends 父类名。 - 传递 构造参数。在子类构造函数体前使用
super关键字调用父类构造器,确保父类初始化所需的变量被正确传入。 - 重写 覆盖逻辑(可选)。在子类中定义与父类同名的方法,并在方法首行添加
@override注解。该方法内的代码将替代 父类原有的默认行为。 - 调用 继承成员。在子类方法或外部实例中,直接通过对象名
**访问**继承来的公开属性与方法,无需重新定义。
class Vehicle {
String type;
Vehicle(this.type);
void start() {
print('$type 引擎已启动');
}
}
class ElectricCar extends Vehicle {
int batteryLevel = 100;
// super 必须放在构造函数的初始化列表或方法体首行
ElectricCar(String type) : super(type);
@override
void start() {
// 保留父类逻辑的同时追加新功能
super.start();
print('接通高压电源');
}
void charge() {
batteryLevel += 10;
print('当前电量: $batteryLevel%');
}
}
阶段二:使用 implements 约束行为规范
当两个类不属于同类,但需要遵循同一套“行为标准”(例如:打印机 和 手机 都需要具备“输出文档”的能力)时,按以下步骤操作:
- 设计 契约类。定义一个仅包含方法签名(或带空实现的普通类)的类,用于规定外部必须提供的 API。Dart 没有独立的
interface关键字,直接使用普通类充当接口。 - 声明 实现关系。在目标类定义处使用
implements关键字,后跟契约类名。支持用逗号分隔多个契约类名,实现多接口接入。 - 重写 全部公开成员。编译器会强制检查 契约类中所有的公开(
public)属性和方法。你必须在当前类中逐一使用@override重新实现它们,即使原契约类已有具体逻辑,也会被完全忽略。 - 填充 内部逻辑。为每个被强制重写的方法编写实际执行代码。此时原契约类的构造函数、私有变量均不可见,当前类从零构建独立状态。
class OutputDevice {
void printData() {}
bool get isConnected => false;
}
class Smartphone implements OutputDevice {
// 必须重写 OutputDevice 的所有公开成员
@override
void printData() {
print('通过蓝牙投屏输出');
}
@override
bool get isConnected => true;
}
阶段三:区分场景与组合使用
实际开发中,需通过明确规则判断关键字选型,并处理复杂组合情况。
| 判断维度 | extends 适用场景 |
implements 适用场景 |
|---|---|---|
| 逻辑关系 | “是” (is-a) 关系。子类天然属于父类的一个分类。 | “具备” (can-do) 关系。实现类仅承诺提供特定能力。 |
| 复用策略 | 直接继承字段、方法与构造函数逻辑,按需修改。 | 抛弃原实现细节,仅保留方法名与参数列表的约定。 |
| 数量上限 | 严格单继承,仅能跟随一个 extends。 |
支持多实现,可并列 implements 多个契约类。 |
| 编译校验 | 仅校验类型兼容性,不强制重写非抽象方法。 | 强校验契约完整性,漏写任一公开成员即阻断编译。 |
- 评估 业务模型。确认新类是“在旧代码基础上微调”,还是“完全重写一套算法以满足外部调用标准”。
- 选定 核心关键字。需要继承现有数据结构和默认行为时,敲入
extends;仅需统一外部调用入口、解耦具体实现时,敲入implements。 - 组合 书写复合类。若业务同时满足继承与契约约束,严格遵循顺序书写:
class 新类 extends 父类 implements 契约A, 契约B。 - 排查 编译报错。若终端输出
must be implemented because it is inherited from,立即定位 缺失的契约方法,并在当前类中补全带@override的方法实现。
// 继承核心数据流,同时实现网络与文件两个接口契约
class DataManager extends BaseRepository implements NetworkProvider, FileStorage {
@override
Future<Map> fetchRemote() => {};
@override
void saveToLocal(String path, Map data) {}
// 可直接使用 BaseRepository 中的 protected 方法或字段
void sync() {
var cached = getCachedData(); // 继承自 BaseRepository
fetchRemote().then((data) => saveToLocal(cached.path, data));
}
}
直接复制上述模板结构,替换业务类名与方法体,即可在 Dart 工程中准确构建类型层级与行为契约。

暂无评论,快来抢沙发吧!