Appearance
第9章:Dart 特殊类与特性
9.1 枚举
枚举是一种特殊的类,用于定义固定值的集合。
枚举的定义
使用 enum 关键字定义枚举:
dart
enum Color {
red,
green,
blue
}枚举的使用
dart
enum Color {
red,
green,
blue
}
void main() {
// 访问枚举值
Color color1 = Color.red;
Color color2 = Color.green;
// 比较枚举值
if (color1 == Color.red) {
print('Color is red');
}
// 枚举值转字符串
print(color1.toString()); // Color.red
// 字符串转枚举值
Color? color3 = Color.values.firstWhere((e) => e.toString() == 'Color.blue', orElse: () => null);
print(color3); // Color.blue
}遍历枚举值
dart
enum Color {
red,
green,
blue
}
void main() {
// 遍历所有枚举值
for (var color in Color.values) {
print(color);
}
}运行结果:
Color.red
Color.green
Color.blue枚举的应用场景
枚举适用于表示固定的状态或选项:
dart
enum Day {
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday
}
enum Status {
pending,
processing,
completed,
failed
}
void main() {
Day today = Day.monday;
Status orderStatus = Status.processing;
print('Today is $today');
print('Order status is $orderStatus');
// 根据枚举值执行不同操作
switch (orderStatus) {
case Status.pending:
print('Order is pending');
break;
case Status.processing:
print('Order is being processed');
break;
case Status.completed:
print('Order is completed');
break;
case Status.failed:
print('Order failed');
break;
}
}运行结果:
Today is Day.monday
Order status is Status.processing
Order is being processed9.2 泛型
泛型是一种允许在定义类、接口和方法时使用类型参数的特性,提高代码的复用性和类型安全性。
泛型的定义
使用 <T> 语法定义泛型:
dart
// 泛型类
class Box<T> {
T value;
Box(this.value);
T getValue() {
return value;
}
}
// 泛型方法
T getFirstElement<T>(List<T> list) {
if (list.isEmpty) {
return null;
}
return list[0];
}泛型类
dart
class Box<T> {
T value;
Box(this.value);
T getValue() {
return value;
}
void setValue(T newValue) {
value = newValue;
}
}
void main() {
// 创建不同类型的 Box
Box<int> intBox = Box(10);
Box<String> stringBox = Box('Hello');
Box<double> doubleBox = Box(3.14);
print(intBox.getValue()); // 10
print(stringBox.getValue()); // Hello
print(doubleBox.getValue()); // 3.14
// 修改值
intBox.setValue(20);
print(intBox.getValue()); // 20
}泛型方法
dart
// 泛型方法
T getFirstElement<T>(List<T> list) {
if (list.isEmpty) {
return null;
}
return list[0];
}
// 泛型函数
void printList<T>(List<T> list) {
for (var item in list) {
print(item);
}
}
void main() {
List<int> numbers = [1, 2, 3, 4, 5];
List<String> names = ['John', 'Alice', 'Bob'];
// 调用泛型方法
int firstNumber = getFirstElement(numbers);
String firstName = getFirstElement(names);
print('First number: $firstNumber'); // 1
print('First name: $firstName'); // John
// 调用泛型函数
print('Numbers:');
printList(numbers);
print('\nNames:');
printList(names);
}运行结果:
First number: 1
First name: John
Numbers:
1
2
3
4
5
Names:
John
Alice
Bob泛型约束
可以使用 extends 关键字限制泛型的类型范围:
dart
// 泛型约束
class NumberBox<T extends num> {
T value;
NumberBox(this.value);
T add(T other) {
return value + other as T;
}
}
void main() {
NumberBox<int> intBox = NumberBox(10);
NumberBox<double> doubleBox = NumberBox(3.14);
print(intBox.add(5)); // 15
print(doubleBox.add(2.86)); // 6.0
// 错误:String 不是 num 的子类
// NumberBox<String> stringBox = NumberBox('Hello');
}泛型的作用
- 避免类型转换:使用泛型可以避免运行时的类型转换,提高代码安全性
- 代码复用:泛型允许编写通用的代码,适用于多种类型
- 类型安全:编译时检查类型,减少运行时错误
9.3 混合模式
混合模式(mixin)是一种实现代码复用的机制,允许一个类继承多个类的特性。
mixin 的定义
使用 mixin 关键字定义混合模式:
dart
mixin CanFly {
void fly() {
print('Flying');
}
}
mixin CanSwim {
void swim() {
print('Swimming');
}
}with 关键字使用
使用 with 关键字将 mixin 应用到类中:
dart
mixin CanFly {
void fly() {
print('Flying');
}
}
mixin CanSwim {
void swim() {
print('Swimming');
}
}
class Animal {
String name;
Animal(this.name);
void eat() {
print('Eating');
}
}
class Duck extends Animal with CanFly, CanSwim {
Duck(String name) : super(name);
void quack() {
print('Quacking');
}
}
void main() {
Duck duck = Duck('Donald');
duck.eat(); // 继承自 Animal
duck.fly(); // 来自 CanFly mixin
duck.swim(); // 来自 CanSwim mixin
duck.quack(); // 自己的方法
}运行结果:
Eating
Flying
Swimming
Quackingmixin 的应用场景
mixin 适用于:
- 代码复用:将通用功能提取到 mixin 中
- 避免多继承冲突:Dart 不支持多继承,但可以通过 mixin 实现类似功能
- 功能组合:通过组合多个 mixin 实现复杂功能
dart
mixin Logger {
void log(String message) {
print('[LOG] $message');
}
}
mixin Validator {
bool validate(String value) {
return value != null && value.isNotEmpty;
}
}
class User with Logger, Validator {
String name;
String email;
User(this.name, this.email);
void register() {
if (validate(name) && validate(email)) {
log('User registered: $name');
} else {
log('Registration failed: invalid data');
}
}
}
void main() {
User user1 = User('John', 'john@example.com');
user1.register();
User user2 = User('', 'alice@example.com');
user2.register();
}运行结果:
[LOG] User registered: John
[LOG] Registration failed: invalid data9.4 实操案例
用枚举、泛型、mixin优化代码,实现复杂逻辑:
电商订单系统
dart
// 枚举:订单状态
enum OrderStatus {
pending,
processing,
shipped,
delivered,
cancelled
}
// 枚举:支付方式
enum PaymentMethod {
creditCard,
paypal,
cashOnDelivery
}
// Mixin:日志功能
mixin Logger {
void log(String message) {
print('[${DateTime.now()}] $message');
}
}
// Mixin:验证功能
mixin Validator {
bool validateEmail(String email) {
return email.contains('@');
}
bool validatePhone(String phone) {
return phone.length >= 10;
}
}
// 泛型类:结果包装器
class Result<T> {
T data;
bool success;
String message;
Result(this.data, this.success, this.message);
}
// 地址类
class Address {
String street;
String city;
String zipCode;
Address(this.street, this.city, this.zipCode);
@override
String toString() {
return '$street, $city, $zipCode';
}
}
// 用户类
class User with Logger, Validator {
String name;
String email;
String phone;
Address address;
User(this.name, this.email, this.phone, this.address);
bool validate() {
if (!validateEmail(email)) {
log('Invalid email');
return false;
}
if (!validatePhone(phone)) {
log('Invalid phone');
return false;
}
return true;
}
}
// 订单项类
class OrderItem {
String productId;
String productName;
int quantity;
double price;
OrderItem(this.productId, this.productName, this.quantity, this.price);
double get total => quantity * price;
}
// 订单类
class Order with Logger {
String orderId;
User user;
List<OrderItem> items;
OrderStatus status;
PaymentMethod paymentMethod;
double totalAmount;
Order(this.orderId, this.user, this.items, this.paymentMethod) {
status = OrderStatus.pending;
totalAmount = calculateTotal();
log('Order created: $orderId');
}
double calculateTotal() {
return items.fold(0, (sum, item) => sum + item.total);
}
void updateStatus(OrderStatus newStatus) {
status = newStatus;
log('Order $orderId status updated to $newStatus');
}
void processPayment() {
log('Processing payment for order $orderId via $paymentMethod');
updateStatus(OrderStatus.processing);
}
void ship() {
updateStatus(OrderStatus.shipped);
}
void deliver() {
updateStatus(OrderStatus.delivered);
}
void cancel() {
updateStatus(OrderStatus.cancelled);
}
void printOrder() {
print('Order ID: $orderId');
print('User: ${user.name}');
print('Address: ${user.address}');
print('Status: $status');
print('Payment Method: $paymentMethod');
print('Items:');
for (var item in items) {
print(' ${item.productName} - ${item.quantity} x ${item.price} = ${item.total}');
}
print('Total: $totalAmount');
}
}
void main() {
// 创建用户
User user = User(
'John Doe',
'john@example.com',
'1234567890',
Address('123 Main St', 'New York', '10001')
);
// 验证用户信息
if (user.validate()) {
// 创建订单项
List<OrderItem> items = [
OrderItem('P001', 'Smartphone', 1, 999.99),
OrderItem('P002', 'Case', 2, 19.99),
OrderItem('P003', 'Screen Protector', 3, 9.99)
];
// 创建订单
Order order = Order('ORD001', user, items, PaymentMethod.creditCard);
// 处理订单
order.printOrder();
order.processPayment();
order.ship();
order.deliver();
}
}运行结果:
[2026-04-02 15:50:00.000] Order created: ORD001
Order ID: ORD001
User: John Doe
Address: 123 Main St, New York, 10001
Status: OrderStatus.pending
Payment Method: PaymentMethod.creditCard
Items:
Smartphone - 1 x 999.99 = 999.99
Case - 2 x 19.99 = 39.98
Screen Protector - 3 x 9.99 = 29.97
Total: 1069.94
[2026-04-02 15:50:00.000] Processing payment for order ORD001 via PaymentMethod.creditCard
[2026-04-02 15:50:00.000] Order ORD001 status updated to OrderStatus.processing
[2026-04-02 15:50:00.000] Order ORD001 status updated to OrderStatus.shipped
[2026-04-02 15:50:00.000] Order ORD001 status updated to OrderStatus.delivered