Dart Class API 详细总结

Dart Class API 详细总结

基于Dart官方API文档与实践经验整理

目录

概述

在Dart中,class是面向对象编程的核心概念。Dart是一门纯面向对象的语言,所有的值都是对象,所有的对象都是类的实例。

核心特性

  • 单继承:每个类只能有一个父类
  • 接口实现:可以实现多个接口
  • 混入支持:通过mixin实现代码复用
  • 构造函数多样性:支持多种构造函数形式
  • 访问控制:通过下划线实现私有成员
  • 泛型支持:支持泛型类和方法
  • 操作符重载:可以重载运算符

类的定义与基础语法

1. 基本类定义

dart 复制代码
// 最简单的类定义
class Person {
  // 类体
}

// 带属性和方法的类
class Student {
  // 实例变量
  String name;
  int age;
  
  // 构造函数
  Student(this.name, this.age);
  
  // 方法
  void introduce() {
    print('我是$name,今年$age岁');
  }
}

2. 访问控制

dart 复制代码
class BankAccount {
  // 公开属性
  String accountNumber;
  
  // 私有属性(以下划线开头)
  double _balance;
  
  BankAccount(this.accountNumber, this._balance);
  
  // 公开方法
  double get balance => _balance;
  
  // 私有方法
  void _validateAmount(double amount) {
    if (amount <= 0) {
      throw ArgumentError('金额必须大于0');
    }
  }
  
  // 公开方法调用私有方法
  void deposit(double amount) {
    _validateAmount(amount);
    _balance += amount;
  }
}

3. 静态成员

dart 复制代码
class MathUtils {
  // 静态常量
  static const double pi = 3.14159;
  
  // 静态变量
  static int calculationCount = 0;
  
  // 静态方法
  static double circleArea(double radius) {
    calculationCount++;
    return pi * radius * radius;
  }
  
  // 静态getter
  static String get info => '已计算$calculationCount次';
}

// 使用静态成员
void main() {
  print(MathUtils.pi); // 3.14159
  print(MathUtils.circleArea(5)); // 78.53975
  print(MathUtils.info); // 已计算1次
}

构造函数详解

1. 默认构造函数

dart 复制代码
class Point {
  double x;
  double y;
  
  // 默认构造函数
  Point(this.x, this.y);
}

// 使用
Point p = Point(3.0, 4.0);

2. 命名构造函数

dart 复制代码
class Rectangle {
  double width;
  double height;
  
  // 默认构造函数
  Rectangle(this.width, this.height);
  
  // 命名构造函数:创建正方形
  Rectangle.square(double side) : width = side, height = side;
  
  // 命名构造函数:从另一个Rectangle创建
  Rectangle.copy(Rectangle other) : width = other.width, height = other.height;
  
  // 命名构造函数:创建单位矩形
  Rectangle.unit() : width = 1.0, height = 1.0;
}

// 使用命名构造函数
Rectangle rect1 = Rectangle(10, 20);
Rectangle square = Rectangle.square(15);
Rectangle copy = Rectangle.copy(rect1);
Rectangle unit = Rectangle.unit();

3. 工厂构造函数

dart 复制代码
class Logger {
  final String name;
  static final Map<String, Logger> _cache = <String, Logger>{};
  
  // 私有构造函数
  Logger._internal(this.name);
  
  // 工厂构造函数 - 实现单例模式
  factory Logger(String name) {
    return _cache.putIfAbsent(name, () => Logger._internal(name));
  }
  
  void log(String message) {
    print('[$name] $message');
  }
}

// 工厂构造函数的高级用法
abstract class Shape {
  factory Shape(String type) {
    switch (type) {
      case 'circle':
        return Circle();
      case 'rectangle':
        return Rectangle.unit();
      default:
        throw ArgumentError('未知的形状类型: $type');
    }
  }
  
  double get area;
}

class Circle implements Shape {
  double radius = 1.0;
  
  @override
  double get area => 3.14159 * radius * radius;
}

4. 重定向构造函数

dart 复制代码
class Person {
  String name;
  int age;
  String email;
  
  // 主构造函数
  Person(this.name, this.age, this.email);
  
  // 重定向构造函数
  Person.withNameAndAge(String name, int age) : this(name, age, '');
  
  // 重定向到命名构造函数
  Person.child(String name) : this.withNameAndAge(name, 0);
}

5. 初始化列表

在Dart语言中,初始化列表(initializer list)通常用于初始化类的实例变量,特别是在构造函数中。初始化列表允许你在对象被完全构造之前,先对某些实例变量进行初始化。这对于执行一些需要在构造函数体之前完成的初始化操作非常有用,比如调用一些需要前置条件的函数或方法。

dart 复制代码
class Circle {
  final double radius;
  final double area;
  final double circumference;
  
  // 使用初始化列表计算derived properties
  Circle(double radius) 
    : this.radius = radius,
      area = 3.14159 * radius * radius,
      circumference = 2 * 3.14159 * radius {
    // 构造函数体(可选)
    print('创建了半径为$radius的圆');
  }
  
  // 断言初始化
  Circle.withValidation(double radius)
    : assert(radius > 0, '半径必须大于0'),
      this.radius = radius,
      area = 3.14159 * radius * radius,
      circumference = 2 * 3.14159 * radius;
}

6. 常量构造函数

dart 复制代码
class ImmutablePoint {
  final double x;
  final double y;
  
  // 常量构造函数
  const ImmutablePoint(this.x, this.y);
  
  // 命名常量构造函数
  const ImmutablePoint.origin() : x = 0, y = 0;
}

// 使用常量构造函数
const point1 = ImmutablePoint(3, 4);
const point2 = ImmutablePoint.origin();

// 编译时常量
const points = [
  ImmutablePoint(0, 0),
  ImmutablePoint(1, 1),
  ImmutablePoint(2, 2),
];

属性与方法

1. 属性定义

dart 复制代码
class Product {
  // 实例变量
  String name;
  double _price; // 私有变量
  
  // 自动生成getter和setter
  String? description;
  
  // 只读属性
  final String id;
  
  // 延迟初始化
  late String category;
  
  Product(this.name, this._price, this.id);
  
  // 自定义getter
  double get price => _price;
  
  // 自定义setter
  set price(double value) {
    if (value < 0) {
      throw ArgumentError('价格不能为负数');
    }
    _price = value;
  }
  
  // 计算属性
  double get priceWithTax => _price * 1.1;
  
  // 只读计算属性
  String get displayName => '$name (¥${_price.toStringAsFixed(2)})';
}

2. 方法定义

dart 复制代码
class Calculator {
  // 实例方法
  double add(double a, double b) {
    return a + b;
  }
  
  // 可选参数方法
  double multiply(double a, [double b = 1.0]) {
    return a * b;
  }
  
  // 命名参数方法
  double calculate({
    required double a,
    required double b,
    required String operation,
  }) {
    switch (operation) {
      case '+':
        return a + b;
      case '-':
        return a - b;
      case '*':
        return a * b;
      case '/':
        if (b == 0) throw ArgumentError('除数不能为0');
        return a / b;
      default:
        throw ArgumentError('不支持的操作: $operation');
    }
  }
  
  // 静态方法
  static double percentage(double value, double percent) {
    return value * (percent / 100);
  }
}

3. Getter和Setter

dart 复制代码
class Temperature {
  double _celsius = 0;
  
  // Getter
  double get celsius => _celsius;
  double get fahrenheit => _celsius * 9 / 5 + 32;
  double get kelvin => _celsius + 273.15;
  
  // Setter
  set celsius(double value) {
    if (value < -273.15) {
      throw ArgumentError('温度不能低于绝对零度');
    }
    _celsius = value;
  }
  
  set fahrenheit(double value) {
    celsius = (value - 32) * 5 / 9;
  }
  
  set kelvin(double value) {
    celsius = value - 273.15;
  }
}

// 使用
Temperature temp = Temperature();
temp.celsius = 25;
print('${temp.celsius}°C = ${temp.fahrenheit}°F = ${temp.kelvin}K');

继承与多态

1. 基本继承

dart 复制代码
// 父类
class Animal {
  String name;
  int age;
  
  Animal(this.name, this.age);
  
  void eat() {
    print('$name正在吃东西');
  }
  
  void sleep() {
    print('$name正在睡觉');
  }
  
  // 虚方法,可以被子类重写
  void makeSound() {
    print('$name发出声音');
  }
}

// 子类
class Dog extends Animal {
  String breed;
  
  // 调用父类构造函数
  Dog(String name, int age, this.breed) : super(name, age);
  
  // 重写父类方法
  @override
  void makeSound() {
    print('$name汪汪叫');
  }
  
  // 子类特有方法
  void wagTail() {
    print('$name摇尾巴');
  }
}

class Cat extends Animal {
  bool isIndoor;
  
  Cat(String name, int age, this.isIndoor) : super(name, age);
  
  @override
  void makeSound() {
    print('$name喵喵叫');
  }
  
  void climb() {
    print('$name在爬树');
  }
}

2. 多态性

dart 复制代码
void demonstratePolymorphism() {
  List<Animal> animals = [
    Dog('旺财', 3, '金毛'),
    Cat('咪咪', 2, true),
    Dog('大黄', 5, '土狗'),
  ];
  
  // 多态:同样的调用,不同的行为
  for (Animal animal in animals) {
    animal.makeSound(); // 根据实际类型调用相应的方法
  }
  
  // 类型检查和转换
  for (Animal animal in animals) {
    if (animal is Dog) {
      animal.wagTail(); // 安全转换
    } else if (animal is Cat) {
      animal.climb();
    }
  }
}

3. 抽象方法和super调用

dart 复制代码
abstract class Vehicle {
  String brand;
  int year;
  
  Vehicle(this.brand, this.year);
  
  // 抽象方法,必须由子类实现
  void start();
  void stop();
  
  // 具体方法,可以被子类使用
  void displayInfo() {
    print('$brand ($year年)');
  }
}

class Car extends Vehicle {
  int doors;
  
  Car(String brand, int year, this.doors) : super(brand, year);
  
  @override
  void start() {
    print('汽车发动引擎');
  }
  
  @override
  void stop() {
    print('汽车停止引擎');
  }
  
  @override
  void displayInfo() {
    super.displayInfo(); // 调用父类方法
    print('门数: $doors');
  }
}

抽象类与接口

1. 抽象类

dart 复制代码
abstract class Shape {
  // 抽象属性(通过getter定义)
  double get area;
  double get perimeter;
  
  // 抽象方法
  void draw();
  
  // 具体方法
  void printInfo() {
    print('面积: $area, 周长: $perimeter');
  }
  
  // 工厂构造函数
  factory Shape.create(String type, List<double> params) {
    switch (type) {
      case 'circle':
        return Circle(params[0]);
      case 'rectangle':
        return Rectangle(params[0], params[1]);
      default:
        throw ArgumentError('不支持的形状类型');
    }
  }
}

class Circle extends Shape {
  final double radius;
  
  Circle(this.radius);
  
  @override
  double get area => 3.14159 * radius * radius;
  
  @override
  double get perimeter => 2 * 3.14159 * radius;
  
  @override
  void draw() {
    print('绘制半径为$radius的圆');
  }
}

2. 接口实现

dart 复制代码
// 隐式接口:任何类都可以作为接口
class Flyable {
  void fly() {
    print('飞行中...');
  }
}

class Swimmable {
  void swim() {
    print('游泳中...');
  }
}

// 实现多个接口
class Duck implements Flyable, Swimmable {
  @override
  void fly() {
    print('鸭子在飞');
  }
  
  @override
  void swim() {
    print('鸭子在游泳');
  }
}

// 同时继承和实现
class Robot extends Machine implements Flyable, Swimmable {
  Robot(String model) : super(model);
  
  @override
  void fly() {
    print('机器人启动飞行模式');
  }
  
  @override
  void swim() {
    print('机器人启动游泳模式');
  }
}

class Machine {
  String model;
  
  Machine(this.model);
  
  void operate() {
    print('$model正在运行');
  }
}

混入(Mixin)

1. 基本Mixin

dart 复制代码
// 定义mixin
mixin Flyable {
  void fly() {
    print('正在飞行');
  }
  
  void land() {
    print('正在降落');
  }
}

mixin Swimmable {
  void swim() {
    print('正在游泳');
  }
  
  void dive() {
    print('正在潜水');
  }
}

// 使用mixin
class Bird with Flyable {
  String name;
  
  Bird(this.name);
  
  void chirp() {
    print('$name在叫');
  }
}

class Fish with Swimmable {
  String species;
  
  Fish(this.species);
}

class Duck extends Bird with Swimmable {
  Duck(String name) : super(name);
  
  @override
  void fly() {
    print('$name鸭子在飞');
  }
}

2. 带约束的Mixin

dart 复制代码
class Animal {
  String name;
  Animal(this.name);
}

// mixin只能被Animal的子类使用
mixin Walker on Animal {
  void walk() {
    print('$name正在走路');
  }
  
  void run() {
    print('$name正在跑步');
  }
}

class Dog extends Animal with Walker {
  Dog(String name) : super(name);
}

class Cat extends Animal with Walker {
  Cat(String name) : super(name);
  
  @override
  void walk() {
    print('$name优雅地走着');
  }
}

3. Mixin的高级用法

dart 复制代码
mixin Serializable {
  Map<String, dynamic> toJson();
  
  void fromJson(Map<String, dynamic> json);
  
  String serialize() {
    return toJson().toString();
  }
}

mixin Cacheable {
  static final Map<String, dynamic> _cache = {};
  
  String get cacheKey;
  
  void cache() {
    _cache[cacheKey] = this;
  }
  
  static T? getCached<T>(String key) {
    return _cache[key] as T?;
  }
}

class User with Serializable, Cacheable {
  String name;
  String email;
  int age;
  
  User(this.name, this.email, this.age);
  
  @override
  String get cacheKey => 'user_$email';
  
  @override
  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'email': email,
      'age': age,
    };
  }
  
  @override
  void fromJson(Map<String, dynamic> json) {
    name = json['name'];
    email = json['email'];
    age = json['age'];
  }
}

枚举类

1. 基本枚举

dart 复制代码
// 简单枚举
enum Color {
  red,
  green,
  blue,
  yellow,
}

// 使用枚举
void useBasicEnum() {
  Color favorite = Color.blue;
  
  print(favorite); // Color.blue
  print(favorite.name); // blue
  print(favorite.index); // 2
  
  // 遍历所有枚举值
  for (Color color in Color.values) {
    print('${color.name}: ${color.index}');
  }
  
  // switch语句
  switch (favorite) {
    case Color.red:
      print('红色');
      break;
    case Color.green:
      print('绿色');
      break;
    case Color.blue:
      print('蓝色');
      break;
    case Color.yellow:
      print('黄色');
      break;
  }
}

2. 增强枚举(Dart 2.17+)

dart 复制代码
enum Planet {
  mercury(3.303e+23, 2.4397e6),
  venus(4.869e+24, 6.0518e6),
  earth(5.976e+24, 6.37814e6),
  mars(6.421e+23, 3.3972e6);
  
  // 枚举构造函数
  const Planet(this.mass, this.radius);
  
  // 实例变量
  final double mass;       // 质量 (kg)
  final double radius;     // 半径 (m)
  
  // 计算属性
  double get surfaceGravity => 6.67300E-11 * mass / (radius * radius);
  
  // 实例方法
  double surfaceWeight(double mass) => mass * surfaceGravity;
  
  // 静态方法
  static Planet? findByName(String name) {
    for (Planet planet in Planet.values) {
      if (planet.name == name) return planet;
    }
    return null;
  }
  
  @override
  String toString() => '${name}: 质量=$mass kg, 半径=$radius m';
}

// 使用增强枚举
void useEnhancedEnum() {
  Planet earth = Planet.earth;
  print(earth.surfaceGravity); // 9.802652743337129
  print(earth.surfaceWeight(70)); // 686.1856920358991
  
  Planet? mars = Planet.findByName('mars');
  print(mars?.toString());
}

3. 实现接口的枚举

dart 复制代码
abstract class Comparable<T> {
  int compareTo(T other);
}

enum Status implements Comparable<Status> {
  pending(0, '待处理'),
  processing(1, '处理中'),
  completed(2, '已完成'),
  cancelled(-1, '已取消');
  
  const Status(this.priority, this.description);
  
  final int priority;
  final String description;
  
  @override
  int compareTo(Status other) => priority.compareTo(other.priority);
  
  bool get isActive => this != Status.cancelled;
  
  Status? get nextStatus {
    switch (this) {
      case Status.pending:
        return Status.processing;
      case Status.processing:
        return Status.completed;
      default:
        return null;
    }
  }
}

扩展方法

1. 基本扩展方法

dart 复制代码
// 为String添加扩展方法
extension StringExtensions on String {
  // 判断是否为邮箱
  bool get isEmail {
    return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(this);
  }
  
  // 首字母大写
  String get capitalize {
    if (isEmpty) return this;
    return '${this[0].toUpperCase()}${substring(1).toLowerCase()}';
  }
  
  // 反转字符串
  String get reverse {
    return split('').reversed.join();
  }
  
  // 移除所有空白字符
  String get removeAllWhitespace {
    return replaceAll(RegExp(r'\s+'), '');
  }
}

// 为int添加扩展方法
extension IntExtensions on int {
  // 判断是否为偶数
  bool get isEven => this % 2 == 0;
  
  // 判断是否为奇数
  bool get isOdd => this % 2 != 0;
  
  // 阶乘
  int get factorial {
    if (this < 0) throw ArgumentError('负数没有阶乘');
    if (this <= 1) return 1;
    return this * (this - 1).factorial;
  }
  
  // 转换为罗马数字
  String get toRoman {
    if (this <= 0 || this > 3999) {
      throw ArgumentError('只支持1-3999的数字');
    }
    
    const values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
    const symbols = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
    
    String result = '';
    int num = this;
    
    for (int i = 0; i < values.length; i++) {
      while (num >= values[i]) {
        result += symbols[i];
        num -= values[i];
      }
    }
    
    return result;
  }
}

// 使用扩展方法
void useExtensions() {
  String email = 'user@example.com';
  print(email.isEmail); // true
  print('hello world'.capitalize); // Hello world
  print('dart'.reverse); // trad
  
  int number = 5;
  print(number.isEven); // false
  print(number.factorial); // 120
  print(number.toRoman); // V
}

2. 泛型扩展

dart 复制代码
// 为List添加扩展方法
extension ListExtensions<T> on List<T> {
  // 安全获取元素
  T? getOrNull(int index) {
    if (index < 0 || index >= length) return null;
    return this[index];
  }
  
  // 分组
  Map<K, List<T>> groupBy<K>(K Function(T) keySelector) {
    Map<K, List<T>> map = {};
    for (T element in this) {
      K key = keySelector(element);
      map.putIfAbsent(key, () => []).add(element);
    }
    return map;
  }
  
  // 去重
  List<T> get distinct {
    return toSet().toList();
  }
  
  // 分批处理
  List<List<T>> chunk(int size) {
    List<List<T>> chunks = [];
    for (int i = 0; i < length; i += size) {
      chunks.add(sublist(i, (i + size > length) ? length : i + size));
    }
    return chunks;
  }
}

// 为Map添加扩展方法
extension MapExtensions<K, V> on Map<K, V> {
  // 安全获取值
  V? getOrNull(K key) => this[key];
  
  // 获取值或默认值
  V getOrDefault(K key, V defaultValue) => this[key] ?? defaultValue;
  
  // 反转键值
  Map<V, K> get inverse {
    return map((key, value) => MapEntry(value, key));
  }
}

3. 条件扩展

dart 复制代码
// 只为特定类型添加扩展
extension NumericStringExtensions on String {
  // 只有数字字符串才能转换
  int? get toIntOrNull {
    return int.tryParse(this);
  }
  
  double? get toDoubleOrNull {
    return double.tryParse(this);
  }
}

// 为可空类型添加扩展
extension NullableExtensions<T> on T? {
  // 如果不为null则执行操作
  R? let<R>(R Function(T) operation) {
    if (this != null) {
      return operation(this!);
    }
    return null;
  }
  
  // 如果为null则返回默认值
  T orElse(T defaultValue) {
    return this ?? defaultValue;
  }
}

泛型类

1. 基本泛型类

dart 复制代码
// 泛型类定义
class Box<T> {
  T? _value;
  
  // 泛型构造函数
  Box([this._value]);
  
  // 泛型方法
  void put(T value) {
    _value = value;
  }
  
  T? get() {
    return _value;
  }
  
  bool get isEmpty => _value == null;
  
  // 类型检查
  bool isType<R>() => _value is R;
  
  // 类型转换
  R? as<R>() => _value as R?;
}

// 使用泛型类
void useGenericClass() {
  Box<String> stringBox = Box<String>('Hello');
  Box<int> intBox = Box<int>(42);
  
  print(stringBox.get()); // Hello
  print(intBox.get()); // 42
  
  stringBox.put('World');
  print(stringBox.get()); // World
}

2. 有界泛型

dart 复制代码
// 泛型约束
class NumberBox<T extends num> {
  T value;
  
  NumberBox(this.value);
  
  // 可以使用num的方法
  T add(T other) => (value + other) as T;
  
  bool get isPositive => value > 0;
  
  String get formattedValue => value.toStringAsFixed(2);
}

// 多重约束
abstract class Serializable {
  Map<String, dynamic> toJson();
}

class DataContainer<T extends Object & Serializable> {
  T data;
  
  DataContainer(this.data);
  
  // 可以安全调用Object和Serializable的方法
  Map<String, dynamic> serialize() {
    return {
      'type': data.runtimeType.toString(),
      'data': data.toJson(),
    };
  }
}

3. 泛型方法

dart 复制代码
class Utility {
  // 泛型方法
  static T? find<T>(List<T> list, bool Function(T) predicate) {
    for (T item in list) {
      if (predicate(item)) return item;
    }
    return null;
  }
  
  // 多个泛型参数
  static Map<K, V> combine<K, V>(List<K> keys, List<V> values) {
    Map<K, V> result = {};
    int length = keys.length < values.length ? keys.length : values.length;
    
    for (int i = 0; i < length; i++) {
      result[keys[i]] = values[i];
    }
    
    return result;
  }
  
  // 泛型约束方法
  static T max<T extends Comparable<T>>(T a, T b) {
    return a.compareTo(b) > 0 ? a : b;
  }
}

操作符重载

1. 算术操作符

dart 复制代码
class Vector2D {
  final double x, y;
  
  const Vector2D(this.x, this.y);
  
  // 加法
  Vector2D operator +(Vector2D other) {
    return Vector2D(x + other.x, y + other.y);
  }
  
  // 减法
  Vector2D operator -(Vector2D other) {
    return Vector2D(x - other.x, y - other.y);
  }
  
  // 乘法(标量)
  Vector2D operator *(double scalar) {
    return Vector2D(x * scalar, y * scalar);
  }
  
  // 除法
  Vector2D operator /(double scalar) {
    if (scalar == 0) throw ArgumentError('除数不能为0');
    return Vector2D(x / scalar, y / scalar);
  }
  
  // 一元负号
  Vector2D operator -() {
    return Vector2D(-x, -y);
  }
  
  @override
  String toString() => 'Vector2D($x, $y)';
}

2. 比较操作符

dart 复制代码
class Money implements Comparable<Money> {
  final double amount;
  final String currency;
  
  const Money(this.amount, this.currency);
  
  // 相等操作符
  @override
  bool operator ==(Object other) {
    return identical(this, other) ||
        other is Money &&
        runtimeType == other.runtimeType &&
        amount == other.amount &&
        currency == other.currency;
  }
  
  @override
  int get hashCode => Object.hash(amount, currency);
  
  // 比较操作符
  @override
  int compareTo(Money other) {
    if (currency != other.currency) {
      throw ArgumentError('不能比较不同货币');
    }
    return amount.compareTo(other.amount);
  }
  
  bool operator <(Money other) => compareTo(other) < 0;
  bool operator <=(Money other) => compareTo(other) <= 0;
  bool operator >(Money other) => compareTo(other) > 0;
  bool operator >=(Money other) => compareTo(other) >= 0;
  
  @override
  String toString() => '$amount $currency';
}

3. 集合操作符

dart 复制代码
class CustomList<T> {
  final List<T> _items = [];
  
  // 索引操作符
  T operator [](int index) => _items[index];
  
  void operator []=(int index, T value) {
    _items[index] = value;
  }
  
  // 添加操作符
  CustomList<T> operator +(CustomList<T> other) {
    CustomList<T> result = CustomList<T>();
    result._items.addAll(_items);
    result._items.addAll(other._items);
    return result;
  }
  
  // 包含操作符(需要定义contains方法)
  bool contains(T element) => _items.contains(element);
  
  void add(T item) => _items.add(item);
  
  int get length => _items.length;
  
  @override
  String toString() => _items.toString();
}

元数据注解

1. 内置注解

dart 复制代码
class Example {
  // 过时注解
  @deprecated
  void oldMethod() {
    print('这个方法已过时');
  }
  
  @Deprecated('使用newMethod()替代')
  void anotherOldMethod() {
    print('另一个过时的方法');
  }
  
  // 重写注解
  @override
  String toString() {
    return 'Example instance';
  }
  
  // 必需注解(需要meta包)
  void processData({
    required String data,
    @required String? optionalData, // 旧式写法
  }) {
    // 处理数据
  }
}

2. 自定义注解

dart 复制代码
// 定义自定义注解
class ApiEndpoint {
  final String path;
  final String method;
  
  const ApiEndpoint(this.path, {this.method = 'GET'});
}

class Cacheable {
  final Duration duration;
  
  const Cacheable({this.duration = const Duration(minutes: 5)});
}

// 使用自定义注解
class UserController {
  @ApiEndpoint('/users', method: 'GET')
  @Cacheable(duration: Duration(minutes: 10))
  List<User> getUsers() {
    // 获取用户列表
    return [];
  }
  
  @ApiEndpoint('/users', method: 'POST')
  User createUser(User user) {
    // 创建用户
    return user;
  }
}

3. 反射和注解处理

dart 复制代码
import 'dart:mirrors';

// 注解处理工具类
class AnnotationProcessor {
  static void processClass(Type type) {
    ClassMirror classMirror = reflectClass(type);
    
    // 处理类级别的注解
    for (InstanceMirror annotation in classMirror.metadata) {
      print('类注解: ${annotation.reflectee}');
    }
    
    // 处理方法注解
    classMirror.declarations.forEach((symbol, declaration) {
      if (declaration is MethodMirror) {
        for (InstanceMirror annotation in declaration.metadata) {
          print('方法${MirrorSystem.getName(symbol)}的注解: ${annotation.reflectee}');
        }
      }
    });
  }
}

性能考虑

1. 构造函数性能

dart 复制代码
// ❌ 性能较差的构造函数
class SlowPerson {
  String name;
  String email;
  DateTime createdAt;
  
  SlowPerson(this.name, this.email) : createdAt = DateTime.now() {
    // 构造函数体中的重计算
    name = name.trim().toLowerCase();
    email = email.trim().toLowerCase();
    
    // 验证逻辑
    if (!email.contains('@')) {
      throw ArgumentError('无效的邮箱地址');
    }
  }
}

// ✅ 性能优化的构造函数
class FastPerson {
  final String name;
  final String email;
  final DateTime createdAt;
  
  // 使用工厂构造函数进行预处理
  factory FastPerson(String name, String email) {
    String cleanName = name.trim().toLowerCase();
    String cleanEmail = email.trim().toLowerCase();
    
    if (!cleanEmail.contains('@')) {
      throw ArgumentError('无效的邮箱地址');
    }
    
    return FastPerson._internal(cleanName, cleanEmail, DateTime.now());
  }
  
  // 私有构造函数,直接赋值
  FastPerson._internal(this.name, this.email, this.createdAt);
}

2. 继承链优化

dart 复制代码
// ❌ 过深的继承链
class A {
  void methodA() {}
}

class B extends A {
  void methodB() {}
}

class C extends B {
  void methodC() {}
}

class D extends C {
  void methodD() {}
}

// ✅ 使用组合和mixin
mixin FeatureA {
  void methodA() {}
}

mixin FeatureB {
  void methodB() {}
}

mixin FeatureC {
  void methodC() {}
}

class OptimizedClass with FeatureA, FeatureB, FeatureC {
  void methodD() {}
}

3. 内存优化

dart 复制代码
// 对象池模式
class ObjectPool<T> {
  final List<T> _pool = [];
  final T Function() _factory;
  
  ObjectPool(this._factory);
  
  T acquire() {
    if (_pool.isNotEmpty) {
      return _pool.removeLast();
    }
    return _factory();
  }
  
  void release(T object) {
    if (_pool.length < 100) { // 限制池大小
      _pool.add(object);
    }
  }
}

// 使用对象池
class ExpensiveObject {
  late List<int> data;
  
  ExpensiveObject() {
    reset();
  }
  
  void reset() {
    data = List.filled(1000, 0);
  }
}

final ObjectPool<ExpensiveObject> pool = 
    ObjectPool(() => ExpensiveObject());

void useObjectPool() {
  ExpensiveObject obj = pool.acquire();
  // 使用对象
  obj.reset(); // 重置状态
  pool.release(obj); // 归还到池中
}

常见陷阱和错误

1. 构造函数陷阱

dart 复制代码
class BadExample {
  String name;
  int age;
  
  // ❌ 错误:尝试在初始化列表中使用this
  // BadExample(String n, int a) : name = this.processName(n), age = a;
  
  // ❌ 错误:final字段必须在构造函数完成前初始化
  final String id = generateId(); // 这可能不是你想要的
  
  BadExample(this.name, this.age);
  
  String processName(String name) => name.trim();
  
  static String generateId() => DateTime.now().millisecondsSinceEpoch.toString();
}

// ✅ 正确的方式
class GoodExample {
  final String name;
  final int age;
  final String id;
  
  GoodExample(String rawName, this.age) 
    : name = rawName.trim(),
      id = DateTime.now().millisecondsSinceEpoch.toString();
  
  // 或使用工厂构造函数
  factory GoodExample.create(String rawName, int age) {
    return GoodExample(rawName.trim(), age);
  }
}

2. 继承和重写陷阱

dart 复制代码
class Parent {
  void method() {
    print('Parent method');
  }
  
  // ❌ 私有方法不能被重写
  void _privateMethod() {
    print('Private method');
  }
}

class Child extends Parent {
  // ❌ 这不是重写,而是创建了新方法
  void _privateMethod() {
    print('Child private method');
  }
  
  // ✅ 正确的重写
  @override
  void method() {
    super.method(); // 可选:调用父类方法
    print('Child method');
  }
}

3. 混入顺序陷阱

dart 复制代码
mixin A {
  void method() => print('A');
}

mixin B {
  void method() => print('B');
}

mixin C {
  void method() => print('C');
}

// 混入顺序很重要
class Example1 with A, B, C {} // method()输出: C
class Example2 with C, B, A {} // method()输出: A
class Example3 with A, C, B {} // method()输出: B

void testMixinOrder() {
  Example1().method(); // C
  Example2().method(); // A  
  Example3().method(); // B
}

最佳实践

1. 类设计原则

dart 复制代码
// ✅ 单一职责原则
class User {
  final String id;
  final String name;
  final String email;
  
  const User({required this.id, required this.name, required this.email});
  
  // 只负责用户数据
}

class UserValidator {
  static bool isValidEmail(String email) {
    return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(email);
  }
  
  static bool isValidName(String name) {
    return name.trim().isNotEmpty && name.length >= 2;
  }
}

class UserRepository {
  Future<User> save(User user) async {
    // 保存用户逻辑
    return user;
  }
  
  Future<User?> findById(String id) async {
    // 查找用户逻辑
    return null;
  }
}

2. 构造函数最佳实践

dart 复制代码
class Product {
  final String id;
  final String name;
  final double price;
  final DateTime createdAt;
  
  // 主构造函数:必需参数
  Product({
    required this.id,
    required this.name,
    required this.price,
  }) : createdAt = DateTime.now();
  
  // 命名构造函数:特殊场景
  Product.withTimestamp({
    required this.id,
    required this.name,
    required this.price,
    required this.createdAt,
  });
  
  // 工厂构造函数:复杂创建逻辑
  factory Product.fromJson(Map<String, dynamic> json) {
    return Product.withTimestamp(
      id: json['id'],
      name: json['name'],
      price: json['price'].toDouble(),
      createdAt: DateTime.parse(json['created_at']),
    );
  }
  
  // 复制构造函数
  Product copyWith({
    String? name,
    double? price,
  }) {
    return Product.withTimestamp(
      id: id,
      name: name ?? this.name,
      price: price ?? this.price,
      createdAt: createdAt,
    );
  }
}

3. 错误处理最佳实践

dart 复制代码
class BankAccount {
  final String accountNumber;
  double _balance;
  
  BankAccount(this.accountNumber, this._balance) {
    if (_balance < 0) {
      throw ArgumentError('初始余额不能为负数');
    }
  }
  
  double get balance => _balance;
  
  void deposit(double amount) {
    if (amount <= 0) {
      throw ArgumentError('存款金额必须大于0');
    }
    _balance += amount;
  }
  
  void withdraw(double amount) {
    if (amount <= 0) {
      throw ArgumentError('取款金额必须大于0');
    }
    if (amount > _balance) {
      throw StateError('余额不足');
    }
    _balance -= amount;
  }
  
  // 安全的取款方法
  bool tryWithdraw(double amount) {
    try {
      withdraw(amount);
      return true;
    } catch (e) {
      return false;
    }
  }
}

4. 不可变性最佳实践

dart 复制代码
// ✅ 不可变类
class ImmutablePoint {
  final double x;
  final double y;
  
  const ImmutablePoint(this.x, this.y);
  
  // 返回新实例而不是修改当前实例
  ImmutablePoint translate(double dx, double dy) {
    return ImmutablePoint(x + dx, y + dy);
  }
  
  ImmutablePoint scale(double factor) {
    return ImmutablePoint(x * factor, y * factor);
  }
  
  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is ImmutablePoint && x == other.x && y == other.y;
  
  @override
  int get hashCode => Object.hash(x, y);
  
  @override
  String toString() => 'Point($x, $y)';
}

5. 文档和测试

dart 复制代码
/// 表示一个二维向量的不可变类
/// 
/// 这个类提供了基本的向量运算,包括加法、减法、点积等。
/// 所有操作都返回新的向量实例,不会修改原有向量。
/// 
/// 示例用法:
/// ```dart
/// var v1 = Vector2D(3, 4);
/// var v2 = Vector2D(1, 2);
/// var sum = v1 + v2; // Vector2D(4, 6)
/// print(v1.magnitude); // 5.0
/// ```
class Vector2D {
  /// X坐标分量
  final double x;
  
  /// Y坐标分量  
  final double y;
  
  /// 创建一个新的二维向量
  /// 
  /// [x] X坐标分量
  /// [y] Y坐标分量
  const Vector2D(this.x, this.y);
  
  /// 零向量常量
  static const Vector2D zero = Vector2D(0, 0);
  
  /// 单位向量常量
  static const Vector2D unitX = Vector2D(1, 0);
  static const Vector2D unitY = Vector2D(0, 1);
  
  /// 向量的模长(大小)
  double get magnitude => math.sqrt(x * x + y * y);
  
  /// 向量加法
  /// 
  /// 返回两个向量相加的结果
  Vector2D operator +(Vector2D other) => Vector2D(x + other.x, y + other.y);
  
  /// 计算两个向量的点积
  /// 
  /// 点积的几何意义是两个向量的模长乘积再乘以它们夹角的余弦值
  double dot(Vector2D other) => x * other.x + y * other.y;
  
  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Vector2D && x == other.x && y == other.y;
  
  @override
  int get hashCode => Object.hash(x, y);
  
  @override
  String toString() => 'Vector2D($x, $y)';
}

总结

Dart的类系统提供了丰富而强大的面向对象编程能力。通过掌握以下关键概念:

  1. 类的基础语法:属性、方法、构造函数
  2. 继承机制:单继承、方法重写、super调用
  3. 接口实现:隐式接口、多接口实现
  4. 混入系统:代码复用、线性化
  5. 泛型支持:类型安全、代码复用
  6. 操作符重载:自然的语法表达
  7. 扩展方法:为现有类型添加功能

结合最佳实践和性能考虑,可以编写出高质量、可维护的Dart代码。记住要遵循单一职责原则,合理使用不可变性,并注意避免常见的陷阱。


本文档基于Dart 3.x版本整理,涵盖了类系统的核心概念和实际应用场景。

相关推荐
cowice4 天前
Dart基础知识
flutter·dart
AhhhhDong11 天前
记录工作中遇到的几个Dart语言的坑和bug
dart
叽哥16 天前
Flutter面试:Dart基础2
flutter·面试·dart
fouryears_2341720 天前
Flutter InheritedWidget 详解:从生命周期到数据流动的完整解析
开发语言·flutter·客户端·dart
华科云商xiao徐25 天前
异步并发×编译性能:Dart爬虫的实战突围
爬虫·数据可视化·dart
dragon72525 天前
dart以同步方式调用异步函数引发的时序bug
dart
叽哥1 个月前
dart学习第 24 节:核心特性实战 —— 天气 API 数据解析
flutter·dart
叽哥1 个月前
dart学习第 23 节: 单元测试入门 —— 保证代码质量
flutter·dart
叽哥1 个月前
dart学习第 22 节:性能优化基础 —— 从代码层面提速
flutter·dart