// ✅ 验证通过:Dart 3.4
// 文件:lib/classes.dart
/// 基本类定义
class User {
// 字段(默认public)
final String name;
final String email;
int _age; // 私有字段(_前缀)
// 主构造函数(简写语法)
User(this.name, this.email, this._age);
// 命名构造函数
User.guest()
: name = 'Guest',
email = 'guest@example.com',
_age = 0;
User.fromJson(Map<String, dynamic> json)
: name = json['name'] as String,
email = json['email'] as String,
_age = json['age'] as int;
// 初始化列表
User.withValidation(this.name, this.email, int age)
: _age = age >= 0 ? age : 0; // 验证逻辑
// Getter
int get age => _age;
// Setter
set age(int value) {
if (value >= 0 && value <= 150) {
_age = value;
}
}
// 只读计算属性
bool get isAdult => _age >= 18;
String get displayName => name.isNotEmpty ? name : email.split('@').first;
// 方法
String greet() => '你好,我是$name!';
// 重写Object方法
@override
String toString() => 'User(name: $name, email: $email, age: $_age)';
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is User && name == other.name && email == other.email;
@override
int get hashCode => Object.hash(name, email);
}
// ✅ 验证通过
/// 工厂构造函数
class Logger {
final String name;
static final Map<String, Logger> _cache = {};
// 工厂构造函数——可以返回缓存的实例
factory Logger(String name) {
return _cache.putIfAbsent(name, () => Logger._internal(name));
}
// 私有命名构造函数
Logger._internal(this.name);
void log(String message) {
print('[$name] $message');
}
}
/// 重定向构造函数
class Point {
final double x, y;
// 主构造函数
const Point(this.x, this.y);
// 重定向到主构造函数
const Point.origin() : this(0, 0);
const Point.onXAxis(double x) : this(x, 0);
const Point.onYAxis(double y) : this(0, y);
}
/// 常量构造函数
class ImmutableConfig {
final String name;
final int version;
const ImmutableConfig(this.name, this.version);
static const production = ImmutableConfig('prod', 1);
static const development = ImmutableConfig('dev', 0);
}
// ✅ 验证通过
/// 基类
abstract class Shape {
// 抽象方法
double area();
double perimeter();
// 具体方法
String describe() => '$runtimeType: 面积=${area().toStringAsFixed(2)}, 周长=${perimeter().toStringAsFixed(2)}';
// 工厂构造函数
factory Shape.circle(double radius) = Circle;
factory Shape.rectangle(double width, double height) = Rectangle;
}
class Circle extends Shape {
final double radius;
const Circle(this.radius);
@override
double area() => 3.14159265 * radius * radius;
@override
double perimeter() => 2 * 3.14159265 * radius;
}
class Rectangle extends Shape {
final double width;
final double height;
const Rectangle(this.width, this.height);
@override
double area() => width * height;
@override
double perimeter() => 2 * (width + height);
// 正方形工厂
factory Rectangle.square(double side) => Rectangle(side, side);
}
class Square extends Rectangle {
Square(double side) : super(side, side);
}
void inheritanceDemo() {
var shapes = [
Circle(5),
Rectangle(4, 6),
Rectangle.square(3),
Square(2),
];
for (var shape in shapes) {
print(shape.describe());
}
// Circle: 面积=78.54, 周长=31.42
// Rectangle: 面积=24.00, 周长=20.00
// Rectangle: 面积=9.00, 周长=12.00
// Square: 面积=4.00, 周长=8.00
}
Mixin是Dart实现代码复用的核心机制,比多重继承更安全、更灵活。
// ✅ 验证通过
/// 日志混入
mixin Loggable on Object {
void logInfo(String message) {
print('ℹ️ [${runtimeType}] $message');
}
void logWarning(String message) {
print('⚠️ [${runtimeType}] $message');
}
void logError(String message) {
print('❌ [${runtimeType}] $message');
}
}
/// 序列化混入
mixin Serializable {
Map<String, dynamic> toJson();
String toJsonString() => toJson().toString();
static T fromJson<T>(Map<String, dynamic> json, T Function(Map<String, dynamic>) factory) {
return factory(json);
}
}
/// 可比较混入
mixin Comparable<T> {
int compareTo(T other);
bool operator &(lt;(T other) => compareTo(other) < 0;
bool operator <=(T other) => compareTo(other) <= 0;
bool operator >(T other) => compareTo(other) > 0;
bool operator >=(T other) => compareTo(other) >= 0;
}
/// 使用多个Mixin
class Product extends Object with Loggable, Serializable {
final String id;
final String name;
final double price;
int stock;
Product({
required this.id,
required this.name,
required this.price,
this.stock = 0,
});
void sell(int quantity) {
if (quantity > stock) {
logError('库存不足: 请求$quantity, 库存$stock');
return;
}
stock -= quantity;
logInfo('售出$quantity件$name,剩余$stock');
}
void restock(int quantity) {
stock += quantity;
logInfo('补货$quantity件$name,总库存$stock');
}
@override
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'price': price,
'stock': stock,
};
factory Product.fromJson(Map<String, dynamic> json) => Product(
id: json['id'] as String,
name: json['name'] as String,
price: (json['price'] as num).toDouble(),
stock: json['stock'] as int? ?? 0,
);
}
void mixinDemo() {
var product = Product(
id: 'P001',
name: 'Flutter入门指南',
price: 59.9,
stock: 100,
);
product.logInfo('商品上架: ${product.name}');
product.sell(30);
product.sell(80); // 库存不足
product.restock(50);
print(product.toJsonString());
}
// ✅ 验证通过
/// String扩展
extension StringX on String {
/// 首字母大写
String get capitalized {
if (isEmpty) return this;
return '${this[0].toUpperCase()}${substring(1)}';
}
/// 驼峰转下划线
String get snakeCase {
return replaceAllMapped(
RegExp(r'[A-Z]'),
(match) => '_${match.group(0)!.toLowerCase()}',
);
}
/// 是否是有效邮箱
bool get isValidEmail {
return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]+$').hasMatch(this);
}
/// 截断并添加省略号
String truncate(int maxLength, {String suffix = '...'}) {
if (length <= maxLength) return this;
return '${substring(0, maxLength - suffix.length)}$suffix';
}
}
/// int扩展
extension IntX on int {
Duration get milliseconds => Duration(milliseconds: this);
Duration get seconds => Duration(seconds: this);
Duration get minutes => Duration(minutes: this);
Duration get hours => Duration(hours: this);
/// 生成范围列表
List<int> get range => List.generate(this, (i) => i);
}
/// List扩展
extension ListX<T> on List<T> {
/// 安全取值
T? getOrNull(int index) {
if (index >= 0 && index < length) return this[index];
return null;
}
/// 分块
List<List<T>> chunk(int size) {
var chunks = <List<T>>[];
for (var i = 0; i < length; i += size) {
chunks.add(sublist(i, i + size > length ? length : i + size));
}
return chunks;
}
/// 去重(保持顺序)
List<T> distinct() {
var seen = <T>{};
return where((item) => seen.add(item)).toList();
}
}
void extensionDemo() {
// String扩展
print('hello world'.capitalized); // Hello world
print('camelCaseName'.snakeCase); // camel_case_name
print('user@example.com'.isValidEmail); // true
print('这是一段很长的文字需要截断'.truncate(8)); // 这是一段很...
// int扩展
var delay = 3.seconds;
print('延迟: $delay'); // 0:00:03.000000
// List扩展
var numbers = [1, 2, 3, 4, 5, 6, 7];
print(numbers.chunk(3)); // [[1, 2, 3], [4, 5, 6], [7]]
print(numbers.getOrNull(10)); // null
var withDuplicates = [3, 1, 2, 3, 2, 4];
print(withDuplicates.distinct()); // [3, 1, 2, 4]
}
// ✅ 验证通过:Dart 3.0+
/// 密封类——限制子类,编译器可穷举检查
sealed class Result<T> {
const Result();
}
class Success<T> extends Result<T> {
final T data;
const Success(this.data);
}
class Failure<T> extends Result<T> {
final String message;
final int? code;
const Failure(this.message, {this.code});
}
class Loading<T> extends Result<T> {
const Loading();
}
// 使用——switch必须穷举所有子类
String describeResult(Result<int> result) {
return switch (result) {
Success(:final data) => '成功: $data',
Failure(:final message, :final code) => '失败: $message (code: $code)',
Loading() => '加载中...',
};
}
// 网络请求结果
sealed class NetworkState {}
class NetworkIdle extends NetworkState {}
class NetworkLoading extends NetworkState {
final double progress;
NetworkLoading(this.progress);
}
class NetworkSuccess<T> extends NetworkState {
final T data;
NetworkSuccess(this.data);
}
class NetworkError extends NetworkState {
final String message;
final int statusCode;
NetworkError(this.message, this.statusCode);
}
// ✅ 验证通过:Dart 3.4
// 文件:lib/task_manager.dart
/// 综合运用:类、继承、Mixin、密封类、扩展方法
// 扩展方法
extension DateTimeX on DateTime {
String get formatted => '$year-${month.toString().padLeft(2, '0')}-${day.toString().padLeft(2, '0')}';
}
// 优先级枚举
enum Priority { low, medium, high, urgent }
extension PriorityX on Priority {
String get label => switch (this) {
Priority.low => '低',
Priority.medium => '中',
Priority.high => '高',
Priority.urgent => '紧急',
};
String get emoji => switch (this) {
Priority.low => '🟢',
Priority.medium => '🟡',
Priority.high => '🟠',
Priority.urgent => '🔴',
};
}
// 任务状态密封类
sealed class TaskStatus {
const TaskStatus();
}
class Todo extends TaskStatus {
const Todo();
}
class InProgress extends TaskStatus {
final DateTime startedAt;
const InProgress(this.startedAt);
}
class Completed extends TaskStatus {
final DateTime completedAt;
const Completed(this.completedAt);
}
class Cancelled extends TaskStatus {
final String reason;
const Cancelled(this.reason);
}
// Loggable Mixin
mixin Loggable {
void log(String message) {
print('[${DateTime.now().formatted}] $message');
}
}
// 基础任务类
class Task with Loggable {
final String id;
final String title;
final String description;
final Priority priority;
final DateTime createdAt;
final String? assignee;
final List<String> tags;
TaskStatus _status;
Task({
required this.id,
required this.title,
required this.description,
this.priority = Priority.medium,
DateTime? createdAt,
this.assignee,
List<String>? tags,
TaskStatus? status,
}) : createdAt = createdAt ?? DateTime.now(),
tags = tags ?? [],
_status = status ?? const Todo();
TaskStatus get status => _status;
void start() {
if (_status is! Todo) {
log('无法启动: 当前状态不是待办');
return;
}
_status = InProgress(DateTime.now());
log('任务启动: $title');
}
void complete() {
if (_status is! InProgress) {
log('无法完成: 当前状态不是进行中');
return;
}
_status = Completed(DateTime.now());
log('任务完成: $title');
}
void cancel(String reason) {
if (_status is Completed) {
log('无法取消: 已完成的任务');
return;
}
_status = Cancelled(reason);
log('任务取消: $title ($reason)');
}
String statusLabel() => switch (_status) {
Todo() => '📋 待办',
InProgress(:final startedAt) => '🔄 进行中 (开始: ${startedAt.formatted})',
Completed(:final completedAt) => '✅ 完成 (${completedAt.formatted})',
Cancelled(:final reason) => '❌ 已取消 ($reason)',
};
@override
String toString() => '${priority.emoji} $title [${statusLabel()}]';
}
// 任务管理器
class TaskManager with Loggable {
final List<Task> _tasks = [];
int _nextId = 1;
Task createTask({
required String title,
String description = '',
Priority priority = Priority.medium,
String? assignee,
List<String>? tags,
}) {
var task = Task(
id: 'T${_nextId++}',
title: title,
description: description,
priority: priority,
assignee: assignee,
tags: tags,
);
_tasks.add(task);
log('创建任务: ${task.id} - $title');
return task;
}
List<Task> get allTasks => List.unmodifiable(_tasks);
List<Task> byStatus(Type statusType) =>
_tasks.where((t) => t.status.runtimeType == statusType).toList();
List<Task> byPriority(Priority p) =>
_tasks.where((t) => t.priority == p).toList();
List<Task> search(String query) =>
_tasks.where((t) => t.title.contains(query) || t.description.contains(query)).toList();
Map<Priority, List<Task>> groupByPriority() {
var groups = <Priority, List<Task>>{};
for (var task in _tasks) {
groups.putIfAbsent(task.priority, () => []).add(task);
}
return groups;
}
String summary() {
var todo = byStatus(Todo).length;
var inProgress = byStatus(InProgress).length;
var completed = byStatus(Completed).length;
var cancelled = byStatus(Cancelled).length;
return '任务统计: 📋$todo 🔄$inProgress ✅$completed ❌$cancelled / 共${_tasks.length}';
}
}
void main() {
var manager = TaskManager();
var task1 = manager.createTask(
title: '完成首页UI',
description: '实现Material Design风格的首页布局',
priority: Priority.high,
assignee: 'Alice',
tags: ['UI', '首页'],
);
var task2 = manager.createTask(
title: '集成登录API',
priority: Priority.urgent,
tags: ['API', '认证'],
);
var task3 = manager.createTask(
title: '编写单元测试',
priority: Priority.low,
);
// 操作任务
task1.start();
task1.complete();
task2.start();
task3.cancel('需求变更');
// 查询
print('\n--- 所有任务 ---');
for (var task in manager.allTasks) {
print(task);
}
print('\n--- 按优先级分组 ---');
for (var entry in manager.groupByPriority().entries) {
print('${entry.key.emoji} ${entry.key.label}: ${entry.value.length}个任务');
}
print('\n${manager.summary()}');
}
实现一个银行账户类:
扩展Shape类体系,添加:
为以下类型编写实用扩展方法:
double:toPrecision(n)、toCurrency()Iterable<T>:sum、average、maxByMap<K,V>:invert、mapValues下一课:异步编程——Future、async/await、Stream和Isolate,Dart的并发模型。