Dart 作为一门纯面向对象语言,其类系统设计既保留了传统面向对象语言的特性,又加入了一些现代化的语法糖。下面我将从实际开发角度,深入剖析 Dart 类的各种特性。
在 Dart 中,类的定义非常直观,但有几个关键细节需要注意:
dart复制class Person {
// 成员变量(实例字段)
String name;
int age;
// 标准构造函数
Person(String name, int age) {
this.name = name;
this.age = age;
}
// 方法
void introduce() {
print('我叫$name,今年$age岁');
}
}
这种写法虽然清晰,但 Dart 提供了更简洁的语法糖:
dart复制class Person {
String name;
int age;
// 语法糖构造函数
Person(this.name, this.age);
void introduce() => print('我叫$name,今年$age岁');
}
实际开发建议:对于简单类,优先使用语法糖形式;当构造函数需要额外逻辑时,再使用完整形式。
命名构造函数在实际项目中非常有用,特别是在需要多种初始化方式时:
dart复制class User {
String username;
String email;
DateTime registerTime;
// 主构造函数
User(this.username, this.email) : registerTime = DateTime.now();
// 从JSON创建用户的命名构造函数
User.fromJson(Map<String, dynamic> json)
: username = json['username'],
email = json['email'],
registerTime = DateTime.parse(json['register_time']);
// 创建匿名用户的命名构造函数
User.anonymous()
: username = 'anonymous',
email = '',
registerTime = DateTime.now();
}
使用场景示例:
dart复制// 从API获取的JSON数据
final apiResponse = {
'username': 'dev_mango',
'email': 'mango@example.com',
'register_time': '2023-01-01T00:00:00Z'
};
// 使用不同构造函数创建对象
final user1 = User('regular', 'regular@example.com');
final user2 = User.fromJson(apiResponse);
final user3 = User.anonymous();
Dart 的私有成员规则与其他语言不同,需要特别注意:
dart复制// bank_account.dart
class BankAccount {
String owner;
double _balance; // 私有变量
BankAccount(this.owner, this._balance);
// 存款方法
void deposit(double amount) {
if (amount > 0) {
_balance += amount;
_logTransaction('存款', amount);
}
}
// 取款方法
bool withdraw(double amount) {
if (amount > 0 && _balance >= amount) {
_balance -= amount;
_logTransaction('取款', amount);
return true;
}
return false;
}
// 私有方法
void _logTransaction(String type, double amount) {
print('$type操作: $amount, 余额: $_balance');
}
// Getter方法
double get balance => _balance;
}
关键注意事项:
Dart 支持单继承,下面是典型的继承示例:
dart复制class Vehicle {
String make;
String model;
int year;
Vehicle(this.make, this.model, this.year);
void start() => print('车辆启动中...');
void stop() => print('车辆停止中...');
void describe() {
print('$year $make $model');
}
}
class Car extends Vehicle {
int doorCount;
Car(String make, String model, int year, this.doorCount)
: super(make, model, year);
@override
void describe() {
super.describe();
print('车门数量: $doorCount');
}
// 特有方法
void honk() => print('嘟嘟!');
}
Dart 的抽象类和接口实现有其独特之处:
dart复制// 抽象类定义行为规范
abstract class Shape {
double get area;
double get perimeter;
void draw();
}
// 接口定义能力
class Drawable {
void draw() => print('绘制中...');
}
class Scalable {
void scale(double factor) => print('缩放比例: $factor');
}
// 实现抽象类和多个接口
class Circle implements Shape, Drawable, Scalable {
double radius;
Circle(this.radius);
@override
double get area => 3.14 * radius * radius;
@override
double get perimeter => 2 * 3.14 * radius;
@override
void draw() => print('绘制圆形,半径: $radius');
@override
void scale(double factor) {
radius *= factor;
print('半径缩放为: $radius');
}
}
Mixin 是 Dart 中实现代码复用的重要方式:
dart复制mixin Swimming {
void swim() => print('游泳中...');
}
mixin Flying {
void fly() => print('飞行中...');
}
class Duck with Swimming, Flying {
String name;
Duck(this.name);
void doEverything() {
swim();
fly();
print('$name 是只全能鸭子');
}
}
Mixin 的特殊用法 - on 关键字限制:
dart复制// 只能在 Animal 或其子类中使用
mixin VeterinaryCare on Animal {
void checkUp() => print('进行健康检查');
}
class Animal {
// ...
}
class Cat extends Animal with VeterinaryCare {
// ...
}
// 错误!Dog 不是 Animal 的子类
// class Dog with VeterinaryCare {}
dart复制// 泛型类
class Box<T> {
T content;
Box(this.content);
T getContent() => content;
void updateContent(T newContent) {
content = newContent;
}
}
// 泛型方法
T findFirst<T>(List<T> items, bool Function(T) test) {
for (var item in items) {
if (test(item)) return item;
}
throw Exception('未找到符合条件的元素');
}
void main() {
// 使用泛型类
var stringBox = Box<String>('Dart');
print(stringBox.getContent()); // Dart
var intBox = Box<int>(42);
print(intBox.getContent()); // 42
// 使用泛型方法
var numbers = [1, 2, 3, 4, 5];
var firstEven = findFirst(numbers, (n) => n % 2 == 0);
print(firstEven); // 2
}
dart复制// 限制 T 必须是 num 或其子类
class Calculator<T extends num> {
T add(T a, T b) => a + b as T;
T subtract(T a, T b) => a - b as T;
}
// 限制多个类型
class DataProcessor<T extends Comparable, U extends Serializable> {
void process(T item1, U item2) {
// ...
}
}
dart复制Future<String> fetchUserData() {
return Future.delayed(Duration(seconds: 2), () {
// 模拟网络请求
final success = Random().nextBool();
if (success) {
return '{"name": "大芒果", "age": 25}';
} else {
throw Exception('网络请求失败');
}
});
}
void main() {
print('开始获取用户数据...');
fetchUserData()
.then((data) {
print('获取成功: $data');
return '处理后的数据';
})
.catchError((error) {
print('发生错误: $error');
return '默认数据';
})
.whenComplete(() => print('操作完成'))
.then((finalData) => print('最终结果: $finalData'));
}
dart复制Future<void> processOrder() async {
try {
print('开始处理订单');
// 并行执行多个异步操作
final results = await Future.wait([
fetchUserInfo(),
fetchProductDetails(),
checkInventory()
]);
final user = results[0];
final product = results[1];
final inStock = results[2];
if (!inStock) {
throw Exception('商品缺货');
}
final paymentResult = await processPayment(user, product);
if (!paymentResult) {
throw Exception('支付失败');
}
await sendConfirmationEmail();
print('订单处理完成');
} catch (e) {
print('订单处理出错: $e');
await sendErrorNotification(e);
rethrow;
} finally {
await cleanupResources();
}
}
dart复制Stream<int> countStream(int max) async* {
for (int i = 1; i <= max; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
void main() async {
final stream = countStream(5);
await for (final number in stream) {
print(number);
}
// 使用 Stream 的各种操作符
countStream(10)
.where((n) => n % 2 == 0)
.map((n) => n * 2)
.listen((n) => print('处理后的数字: $n'));
}
Future 未捕获异常
dart复制// 错误示范
Future<void> riskyOperation() async {
throw Exception('出错了');
}
void main() {
riskyOperation(); // 异常会被静默丢弃
}
// 正确做法
void main() async {
try {
await riskyOperation();
} catch (e) {
print('捕获到异常: $e');
}
}
过度使用 async/await
dart复制// 不必要地使用 await
Future<String> getData() async {
final data = await fetchData(); // 立即 await
return process(data);
}
// 更好的写法
Future<String> getData() {
return fetchData().then(process);
}
Isolate 的使用
dart复制Future<void> heavyComputation() async {
final receivePort = ReceivePort();
await Isolate.spawn(_computeInIsolate, receivePort.sendPort);
final result = await receivePort.first;
print('计算结果: $result');
}
void _computeInIsolate(SendPort sendPort) {
// 在独立Isolate中执行耗时计算
final result = doExpensiveCalculation();
sendPort.send(result);
}
Stream 的防抖与节流
dart复制extension StreamExtensions<T> on Stream<T> {
Stream<T> debounce(Duration duration) {
return transform(
StreamTransformer.fromHandlers(
handleData: (data, sink) async {
await Future.delayed(duration);
sink.add(data);
},
),
);
}
}
code复制lib/
├── models/ # 数据模型
├── services/ # 业务逻辑
├── repositories/ # 数据访问
├── utils/ # 工具类
└── main.dart # 应用入口
dart复制class ApiService {
final HttpClient client;
ApiService(this.client);
Future<dynamic> get(String url) async {
// 实现网络请求
}
}
class UserRepository {
final ApiService apiService;
UserRepository(this.apiService);
Future<User> getUser(int id) async {
final data = await apiService.get('/users/$id');
return User.fromJson(data);
}
}
void main() {
// 依赖注入
final client = HttpClient();
final apiService = ApiService(client);
final userRepo = UserRepository(apiService);
// 使用
userRepo.getUser(1).then(print);
}
dart复制// 测试用例示例
void main() {
group('UserRepository', () {
late UserRepository repository;
late MockApiService mockApiService;
setUp(() {
mockApiService = MockApiService();
repository = UserRepository(mockApiService);
});
test('getUser returns User when API succeeds', () async {
when(mockApiService.get(any)).thenAnswer(
(_) async => {'id': 1, 'name': '测试用户'}
);
final user = await repository.getUser(1);
expect(user, isA<User>());
expect(user.name, '测试用户');
});
test('getUser throws when API fails', () async {
when(mockApiService.get(any)).thenThrow(Exception('API错误'));
expect(() => repository.getUser(1), throwsException);
});
});
}
掌握这些 Dart 高级特性后,你就能在 Flutter 开发中游刃有余。记住,理解原理比记住语法更重要,多实践才能真正掌握这些概念。