1. Dart语言核心语法解析
Dart作为Flutter框架的官方语言,其语法设计兼具简洁性和表达力。对于准备使用Flutter开发OpenHarmonyOS应用的开发者而言,深入理解Dart的函数、类和构造函数机制至关重要。这部分内容将为你后续的跨平台开发打下坚实基础。
1.1 函数定义与参数传递
Dart中的函数定义遵循以下基本结构:
dart复制返回类型 函数名(参数列表) {
函数体
}
实际开发中最常用的三种参数传递方式各有特点:
必传参数是最基础的参数类型,调用时必须按顺序提供所有参数。这种设计保证了函数调用的确定性,适合参数数量固定且含义明确的场景。例如用户注册函数:
dart复制void registerUser(String username, String password, int age) {
// 注册逻辑
}
可选位置参数使用方括号[]声明,适合参数有明确顺序但非必填的场景。比如搜索功能:
dart复制void search(String keyword, [int page = 1, int pageSize = 10]) {
// 搜索逻辑
}
这里page和pageSize有默认值,调用时可选择性提供。
可选命名参数通过花括号{}定义,调用时使用参数名:值的形式,不依赖顺序。这种参数特别适合配置类函数:
dart复制void showDialog({
required String title,
String? content,
bool dismissible = true
}) {
// 对话框显示逻辑
}
注意required关键字可以确保某个命名参数必须提供。
提示:当参数超过3个时,优先考虑使用命名参数,这会显著提升代码可读性。根据Flutter官方代码统计,约78%的组件属性都采用命名参数形式。
1.2 匿名函数与箭头函数
匿名函数(也称lambda表达式)在Dart中应用广泛,特别是在集合操作和事件处理中。其基本形式为:
dart复制(参数) {
函数体
}
实际案例:列表遍历
dart复制var numbers = [1, 2, 3];
numbers.forEach((number) {
print(number * 2);
});
箭头函数是匿名函数的简写形式,当函数体只有单条表达式时可用:
dart复制numbers.map((number) => number * 2).toList();
在Flutter框架中,这种简洁的语法被大量使用。例如构建UI时:
dart复制Button(
onPressed: () => _handleClick(), // 箭头函数
child: Text('Submit')
)
1.3 函数类型与高阶函数
Dart中函数是一等公民,可以作为参数传递或赋值给变量。函数类型使用Function表示:
dart复制typedef Filter = bool Function(int); // 定义函数类型
List<int> filterNumbers(List<int> list, Filter filter) {
return list.where(filter).toList();
}
// 使用
var evenNumbers = filterNumbers([1,2,3,4], (n) => n % 2 == 0);
这种特性在Flutter的状态管理和事件处理中极为常见。例如Provider包中的回调机制就大量使用了高阶函数。
2. Dart中的类与对象系统
2.1 类的基本结构
Dart是面向对象语言,类定义包含属性和方法:
dart复制class Person {
// 实例变量
String name;
int age;
// 构造函数
Person(this.name, this.age);
// 方法
void introduce() {
print('我是$name,今年$age岁');
}
// Getter
String get info => '$name ($age)';
// Setter
set updateAge(int newAge) {
age = newAge;
}
}
在Flutter开发中,这种类结构常用于数据模型定义。例如定义一个简单的用户模型:
dart复制class User {
final String id;
final String email;
String? displayName;
User({required this.id, required this.email, this.displayName});
// 从JSON创建用户的工厂方法
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'],
email: json['email'],
displayName: json['displayName']
);
}
}
2.2 构造函数详解
Dart提供了多种构造函数形式,满足不同场景需求:
默认构造函数是最常用的形式,通常使用简洁的语法糖:
dart复制class Point {
final double x;
final double y;
Point(this.x, this.y);
}
命名构造函数允许一个类有多个构造函数,通过不同名称区分用途:
dart复制class Point {
// ...其他代码
// 从极坐标创建点
Point.fromPolar(double radius, double angle)
: x = radius * cos(angle),
y = radius * sin(angle);
// 原点
Point.origin() : x = 0, y = 0;
}
工厂构造函数在需要控制实例创建时使用,比如从缓存返回已有实例:
dart复制class Logger {
static final Map<String, Logger> _cache = {};
final String name;
factory Logger(String name) {
return _cache.putIfAbsent(name, () => Logger._internal(name));
}
Logger._internal(this.name);
}
在Flutter开发中,工厂构造函数常用于:
- 从JSON创建对象
- 实现单例模式
- 返回子类实例
2.3 初始化列表与final变量
Dart的构造函数支持初始化列表,这在需要验证参数或初始化final变量时特别有用:
dart复制class ImmutablePoint {
final double x;
final double y;
final double distance;
ImmutablePoint(this.x, this.y) : distance = sqrt(x*x + y*y) {
if (x.isNaN || y.isNaN) {
throw ArgumentError('坐标不能为NaN');
}
}
}
初始化列表在Flutter的Widget构建中很常见,例如:
dart复制class MyButton extends StatelessWidget {
final String text;
final VoidCallback onPressed;
const MyButton({
required this.text,
required this.onPressed,
}) : assert(text != null),
assert(onPressed != null);
}
3. 高级类特性
3.1 继承与多态
Dart使用单继承模型,通过extends关键字实现:
dart复制class Animal {
void eat() => print('Eating...');
}
class Dog extends Animal {
@override
void eat() {
super.eat();
print('Dog is eating');
}
void bark() => print('Barking!');
}
在Flutter中,继承常用于创建自定义Widget:
dart复制class CustomAppBar extends AppBar {
CustomAppBar({Key? key, required String title})
: super(
key: key,
title: Text(title),
elevation: 0,
);
}
3.2 接口与抽象类
Dart没有专门的interface关键字,任何类都可以作为接口。抽象类则使用abstract声明:
dart复制abstract class Shape {
double get area;
void draw();
}
class Circle implements Shape {
final double radius;
Circle(this.radius);
@override
double get area => pi * radius * radius;
@override
void draw() => print('Drawing circle');
}
Flutter框架中大量使用抽象类定义核心接口,例如:
dart复制abstract class State<T extends StatefulWidget> {
// 必须实现的方法
Widget build(BuildContext context);
// 可选覆盖的方法
void didChangeDependencies() {}
}
3.3 Mixin机制
Mixin是Dart中实现代码复用的重要方式,通过with关键字使用:
dart复制mixin Logging {
void log(String message) => print('Log: $message');
}
class Service with Logging {
void performTask() {
log('Task started');
// 执行任务
log('Task completed');
}
}
Flutter中的典型应用是SingleTickerProviderStateMixin:
dart复制class _MyAnimationState extends State<MyAnimation>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this, // 使用mixin提供的功能
duration: Duration(seconds: 1)
);
}
}
4. 实战:构建Flutter数据模型
结合上述知识,我们来看一个完整的Flutter数据模型示例:
dart复制import 'dart:convert';
class Product {
final String id;
final String name;
final double price;
final int stock;
final List<String> categories;
Product({
required this.id,
required this.name,
required this.price,
this.stock = 0,
this.categories = const [],
});
// 命名构造函数:从JSON创建
factory Product.fromJson(Map<String, dynamic> json) {
return Product(
id: json['id'],
name: json['name'],
price: json['price']?.toDouble() ?? 0.0,
stock: json['stock'] ?? 0,
categories: List<String>.from(json['categories'] ?? []),
);
}
// 转换为JSON
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'price': price,
'stock': stock,
'categories': categories,
};
// 拷贝方法
Product copyWith({
String? id,
String? name,
double? price,
int? stock,
List<String>? categories,
}) {
return Product(
id: id ?? this.id,
name: name ?? this.name,
price: price ?? this.price,
stock: stock ?? this.stock,
categories: categories ?? this.categories,
);
}
// 重写toString
@override
String toString() => 'Product(${jsonEncode(toJson())})';
// 重写==和hashCode
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Product &&
runtimeType == other.runtimeType &&
id == other.id;
@override
int get hashCode => id.hashCode;
}
这个模型类展示了Dart的核心特性在实际开发中的应用:
- 使用required标记必要参数
- 提供默认参数值
- 实现fromJson工厂构造函数
- 添加toJson方法
- 实现copyWith模式(类似不可变对象的更新)
- 重写操作符和toString
在Flutter中,这样的模型类可以很好地与JSON序列化和状态管理配合使用。
