Skip to content

第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 processed

9.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');
}

泛型的作用

  1. 避免类型转换:使用泛型可以避免运行时的类型转换,提高代码安全性
  2. 代码复用:泛型允许编写通用的代码,适用于多种类型
  3. 类型安全:编译时检查类型,减少运行时错误

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
Quacking

mixin 的应用场景

mixin 适用于:

  1. 代码复用:将通用功能提取到 mixin 中
  2. 避免多继承冲突:Dart 不支持多继承,但可以通过 mixin 实现类似功能
  3. 功能组合:通过组合多个 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 data

9.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

© 2026 编程马·菜鸟教程 版权所有