extends(继承)
就像孩子继承父亲的姓氏和家产:
-
只能有一个父亲(单继承)
-
会继承父亲的所有特征和财产(属性和方法)
-
可以覆盖(重写)父亲的一些特征
// 父类
class Animal {
void eat() => print('吃东西');
}
// 子类
class Dog extends Animal {
// 自动获得了 eat() 方法
// 可以重写父类方法
@override
void eat() => print('啃骨头');
}
with(混入)
就像给人穿衣服:
-
可以穿多件衣服(多个 mixin)
-
每件衣服都给你增加一些功能
-
后穿的衣服(后面的 mixin)会覆盖前面相同的功能
// 定义 mixin
mixin Swimming {
void swim() => print('会游泳');
}
mixin Flying {
void fly() => print('会飞');
}
// 使用 mixin
class Duck extends Animal with Swimming, Flying {
// 同时具备:
// - Animal 的 eat()
// - Swimming 的 swim()
// - Flying 的 fly()
}
主要区别
-
数量限制:
-
extends 只能继承一个类
-
with 可以混入多个 mixin
-
-
使用场景:
-
extends 用于表示"是一个"的关系(狗是一种动物)
-
with 用于表示"具有某种能力"的关系(鸭子具有游泳能力)
-
-
代码复用方式:
- extends 是垂直方向的继承关系
- with 是水平方向的功能扩展
mixin 是什么?
mixin 是一种代码复用的方式,可以理解为一组可以被重复使用的方法和属性的集合。就像是一个"功能包":
-
你可以把常用的功能打包起来
-
需要的时候用 with 关键字把这个"功能包"混入到任何类中
基本用法
// 定义一个 mixin
mixin Logger {
void log(String msg) {
print('日志: $msg');
}
}
// 使用 mixin
class UserService with Logger {
void saveUser() {
log('保存用户信息');
// 可以直接使用 mixin 中的方法
}
}
mixin 的特点
- 可以包含方法和属性
mixin Musical {
String instrument = '钢琴'; // 属性
void playMusic() { // 方法
print('演奏$instrument');
}
}
- 可以使用多个 mixin
class SuperStar with Singer, Dancer, Actor {
// 同时具备唱歌、跳舞、演戏的能力
}
- 可以限制使用范围
// 只有 Performer 类或其子类才能使用这个 mixin
mixin VIP on Performer {
void vipService() {
print('享受 VIP 服务');
}
}
- 可以访问和重写方法
mixin A {
void method() => print('A');
}
mixin B {
void method() => print('B');
}
// C 会使用最后一个 mixin (B) 的 method 实现
class C with A, B {
// method() 输出 'B'
}
使用场景
- 共享功能:
mixin HttpHandler {
Future<void> get(String url) { /* ... */ }
Future<void> post(String url) { /* ... */ }
}
// 多个类都需要处理 HTTP 请求
class UserApi with HttpHandler { /* ... */ }
class ProductApi with HttpHandler { /* ... */ }
- 状态管理:
mixin LoadingState {
bool _isLoading = false;
bool get isLoading => _isLoading;
void startLoading() {
_isLoading = true;
}
void stopLoading() {
_isLoading = false;
}
}
总的来说,mixin 是一种非常灵活的代码复用方式,特别适合那些需要在多个不相关的类之间共享功能的场景。它比继承更灵活,因为可以混入多个 mixin,而且不会产生复杂的继承层次结构。