ZetCode

Dart 中的类

最后修改于 2025 年 5 月 25 日

在本文中,我们将探讨 Dart 中的类,这是 Dart 编程语言的一项强大功能,支持面向对象编程 (OOP)。

Dart 类概述

类是 Dart 中面向对象编程的核心。它们充当创建对象的 **蓝图**,封装 **数据** 和 **行为**。本教程全面介绍了 Dart 类,从基本类定义到 **混合(mixins)**、**扩展(extensions)** 和 **抽象类(abstract classes)** 等高级概念。

通过利用 Dart 的类系统,开发人员可以编写清晰、可重用且模块化的代码。实现 **封装(encapsulation)**、**继承(inheritance)** 和 **多态(polymorphism)** 的能力,使 Dart 的类结构成为设计可伸缩应用程序的重要工具。

功能 描述 示例
类定义 创建对象的蓝图 class Point { ... }
构造函数 初始化对象的函数 Point(this.x, this.y);
属性(Properties) 类中的变量 double x, y;
方法 类中的函数 void move() { ... }
继承 支持创建子类 class Vector extends Point {}
混合(Mixins) 允许跨类共享行为 class Robot with Walker {}
抽象类 定义结构而不实现 abstract class Shape { ... }
扩展(Extensions) 为现有类添加功能 extension on String { ... }

Dart 中的 **类** 是用户定义的类型,它结合了 **状态**(属性)和 **行为**(方法)。它允许开发人员模拟现实世界的实体,定义对象之间的关系,并强制执行结构化编程。

基本类定义

Dart 中的类使用 `class` 关键字后跟类名来定义。类的主体包含其属性(数据)和方法(行为)。下面是一个表示二维空间点的类的简单示例:

basic_class.dart
class Point {
  // Instance variables
  double x;
  double y;
  
  // Constructor
  Point(this.x, this.y);
  
  // Instance method
  void move(double dx, double dy) {
    x += dx;
    y += dy;
  }
  
  // Overriding toString()
  @override
  String toString() => 'Point($x, $y)';
}

void main() {
  // Create an instance
  var p = Point(3.0, 4.0);
  print(p); // Uses toString()
  
  // Access properties and methods
  p.move(1.0, -1.0);
  print('New position: (${p.x}, ${p.y})');
}

此示例演示了 Dart 类的几个关键方面。`Point` 类有两个实例变量(`x` 和 `y`),一个初始化这些变量的构造函数,一个移动点的函数,以及一个重写的 `toString` 函数。

`main` 函数展示了如何创建类的实例并与其成员进行交互。构造函数语法 `Point(this.x, this.y)` 是 Dart 中将构造函数参数分配给实例变量的简写。

$ dart run basic_class.dart
Point(3.0, 4.0)
New position: (4.0, 3.0)

构造函数和初始化

Dart 提供了多种初始化类实例的方法。构造函数可以是简单的也可以是复杂的,并提供命名参数、初始化列表和工厂构造函数等选项。以下是一个展示这些功能的更高级示例:

constructors.dart
class Rectangle {
  final double width;
  final double height;
  final String color;
  
  // Main constructor
  Rectangle(this.width, this.height, [this.color = 'black']);
  
  // Named constructor
  Rectangle.square(double size, String color) 
    : this(size, size, color);
  
  // Constructor with initializer list
  Rectangle.fromJson(Map<String, dynamic> json)
    : width = json['width'],
      height = json['height'],
      color = json['color'] ?? 'black';
  
  // Factory constructor
  factory Rectangle.fromString(String dimensions) {
    var parts = dimensions.split('x');
    return Rectangle(
      double.parse(parts[0]),
      double.parse(parts[1])
    );
  }
  
  double get area => width * height;
}

void main() {
  var rect1 = Rectangle(10.0, 20.0);
  var rect2 = Rectangle.square(15.0, 'red');
  var rect3 = Rectangle.fromJson({'width': 5.0, 'height': 8.0});
  var rect4 = Rectangle.fromString('12x24');
  
  print('Area of rect1: ${rect1.area}');
  print('Area of rect2: ${rect2.area}');
  print('Area of rect3: ${rect3.area}');
  print('Area of rect4: ${rect4.area}');
}

此示例展示了构建 `Rectangle` 对象的四种不同方式。主构造函数使用带可选颜色参数的位置参数。命名构造函数 `Rectangle.square` 提供了一种创建方形矩形的方法。`fromJson` 构造函数演示了用于处理输入数据的初始化列表语法。`fromString` 工厂构造函数展示了如何实现替代的对象创建逻辑。`area` getter 演示了计算属性。

$ dart run constructors.dart
Area of rect1: 200.0
Area of rect2: 225.0
Area of rect3: 40.0
Area of rect4: 288.0

继承和多态

Dart 支持单继承,其中一个类可以扩展另一个类。以下示例演示了继承、方法重写和多态:

inheritance.dart
class Shape {
  final String color;
  
  Shape(this.color);
  
  double get area => 0;
  
  void describe() {
    print('This $runtimeType has color $color and area $area');
  }
}

class Circle extends Shape {
  final double radius;
  
  Circle(String color, this.radius) : super(color);
  
  @override
  double get area => 3.14159 * radius * radius;
}

class Square extends Shape {
  final double side;
  
  Square(String color, this.side) : super(color);
  
  @override
  double get area => side * side;
}

void main() {
  var shapes = [
    Circle('red', 5.0),
    Square('blue', 4.0),
    Shape('green')
  ];
  
  for (var shape in shapes) {
    shape.describe();
  }
}

`Shape` 类作为基类,具有 `area` 的默认实现和 `describe` 函数。`Circle` 和 `Square` 类扩展 `Shape` 并用其特定实现重写 `area` getter。`main` 函数通过基础类接口统一处理不同形状类型来演示多态。`runtimeType` 属性展示了 Dart 在运行时获取对象实际类型的内置支持。

$ dart run inheritance.dart
This Circle has color red and area 78.53975
This Square has color blue and area 16.0
This Shape has color green and area 0

混合(Mixins)和组合(Composition)

Dart 使用混合(mixins)来跨多个类层次结构共享代码。混合(mixin)是一种在不使用继承的情况下将类代码重用于多个类层次结构的方法。以下示例演示了混合(mixins)和组合(composition):

mixins.dart
// Mixins can't have constructors
mixin Logger {
  void log(String message) {
    print('Log: $message - ${DateTime.now()}');
  }
}

mixin JsonSerializable {
  String toJsonString() {
    return '{"type": "$runtimeType"}';
  }
}

class Person with Logger {
  final String name;
  final int age;
  
  Person(this.name, this.age);
  
  void celebrateBirthday() {
    age++;
    log('$name is now $age years old');
  }
}

class Product with Logger, JsonSerializable {
  final String id;
  final double price;
  
  Product(this.id, this.price);
  
  void applyDiscount(double percent) {
    final discount = price * (percent / 100);
    log('Applying $percent% discount (\$$discount) to product $id');
  }
}

void main() {
  var person = Person('Alice', 30);
  person.celebrateBirthday();
  
  var product = Product('12345', 99.99);
  product.applyDiscount(10);
  print(product.toJsonString());
}

`Logger` 和 `JsonSerializable` 混合(mixins)提供了可重用的功能,可以添加到任何类中。`Person` 类仅使用 `Logger` 混合(mixin),而 `Product` 使用两个混合(mixins)。混合(mixins)使用 `with` 关键字包含。这种方法允许代码重用,而没有单继承的限制,因为一个类可以在扩展另一个类的同时使用多个混合(mixins)。

$ dart run mixins.dart
Log: Alice is now 31 years old - 2025-05-25 14:30:45.123456
Log: Applying 10% discount ($9.999) to product 12345 - 2025-05-25 14:30:45.123456
{"type": "Product"}

高级类特性

Dart 提供了几项高级类功能,包括抽象类、接口、扩展方法和运算符重载。以下示例演示了这些概念:

advanced_features.dart
// Abstract class
abstract class Animal {
  String get name;
  void makeSound();
}

// Interface (implicit in Dart)
class Bird {
  void fly() => print('Flying high');
}

// Class implementing multiple interfaces
class Parrot extends Animal implements Bird {
  @override
  final String name;
  
  Parrot(this.name);
  
  @override
  void makeSound() => print('$name says: Squawk!');
  
  @override
  void fly() => print('$name is flying in circles');
  
  // Operator overloading
  Parrot operator +(Parrot other) => Parrot('$name & ${other.name}');
}

// Extension method
extension on Parrot {
  void repeat(String phrase) {
    print('$name repeats: $phrase $phrase $phrase');
  }
}

void main() {
  var polly = Parrot('Polly');
  var matey = Parrot('Matey');
  
  polly.makeSound();
  polly.fly();
  
  var couple = polly + matey;
  print('New parrot: ${couple.name}');
  
  // Using extension method
  polly.repeat('Hello');
}

`Animal` 抽象类定义了一个 `Parrot` 实现的接口。Dart 没有单独的接口关键字 - 任何类都可以作为接口。`Parrot` 类还实现了 `Bird` 接口。通过 `+` 运算符演示了运算符重载,并且扩展方法在不修改其源代码的情况下为 `Parrot` 类添加了功能。这些功能在设计类层次结构和扩展现有功能方面提供了灵活性。

$ dart run advanced_features.dart
Polly says: Squawk!
Polly is flying in circles
New parrot: Polly & Matey
Polly repeats: Hello Hello Hello

来源

Dart 语言:类
Dart 语言:混合(Mixins)
Dart 语言:扩展(Extensions)

类是 Dart 面向对象编程模型的基础。它们提供了数据和行为的封装,通过类层次结构支持继承和多态,并通过混合(mixins)实现代码重用。Dart 的类系统旨在清晰且富有表现力,同时支持现代编程模式。理解类对于有效的 Dart 编程至关重要,从简单的数据结构到复杂的应用程序架构。

作者

我叫 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。到目前为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教学编程方面拥有十多年的经验。

列出 所有 Dart 教程