深入了解 Getter 和 Setter
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 33 课,共 110 课。
将 getter 和 setter 与私有字段结合使用,可以成为封装的强大工具。它们让你在提供简洁的公共接口的同时,完全掌控数据的访问和修改方式。
一种常见模式是将私有字段与公共 getter 和包含验证逻辑的 setter 配对:
class Temperature {
double _celsius = 0;
double get celsius => _celsius;
set celsius(double value) {
if (value < -273.15) {
_celsius = -273.15; // 最低为绝对零度
} else {
_celsius = value;
}
}
}Setter 可以执行业务规则,确保对象始终处于有效状态。
你还可以创建计算属性获取器,从私有数据中推导出值:
class Rectangle {
double _width;
double _height;
Rectangle(this._width, this._height);
double get area => _width * _height; // 计算得出
double get perimeter => 2 * (_width + _height);
double get width => _width;
set width(double value) {
if (value > 0) _width = value;
}
}有时你只想提供只读访问权限。只需提供 getter,不提供 setter:
class Order {
final DateTime _createdAt = DateTime.now();
DateTime get createdAt => _createdAt; // 只读
}这种模式让外部代码可以查看数据,同时防止任何修改,私有字段与仅有的 getter 结合,实现了真正的只读访问。
挑战
简单让我们构建一个商品库存系统,展示 getter 和 setter 如何控制数据访问。你将创建一个类,在保护内部数据的同时提供计算属性和验证功能。
你需要将代码分成两个文件:
product.dart:定义一个Product类,通过适当的封装来管理库存。你的商品类应包含:- 一个公有的
String name - 一个私有的
double _price - 一个私有的
int _quantity - 一个接收这三个值的构造函数
- 一个返回私有价格的 getter
price - 一个只接受大于
0的值的 setterprice(忽略无效值) - 一个返回私有数量的 getter
quantity - 一个只接受大于或等于
0的值的 setterquantity(忽略负值) - 一个返回
_price * _quantity的计算 gettertotalValue - 一个计算 getter
isInStock,当数量大于0时返回true - 一个只读 getter
sku,通过返回名称的前 3 个字符的大写形式,再接上数量来生成简单的 SKU(例如,数量为 25 的 "Laptop" 对应LAP25) - 一个用于显示商品详情的方法
displayProduct()
- 一个公有的
main.dart:导入商品类,并演示 getter 和 setter 如何控制访问:- 创建一个名为
'Laptop'、价格为999.99、数量为25的商品 - 调用
displayProduct() - 打印
In stock: [isInStock] - 打印
SKU: [sku] - 尝试将价格设为
-50.0(应被忽略) - 将价格设为
899.99(有效更改) - 尝试将数量设为
-10(应被忽略) - 将数量设为
0(有效更改) - 调用
displayProduct() - 打印
In stock: [isInStock] - 打印
SKU: [sku]
- 创建一个名为
displayProduct() 方法应按以下格式打印:
--- Product Info ---
Name: [name]
Price: $[price]
Quantity: [quantity]
Total Value: $[totalValue]预期输出:
--- Product Info ---
Name: Laptop
Price: $999.99
Quantity: 25
Total Value: $24999.75
In stock: true
SKU: LAP25
--- Product Info ---
Name: Laptop
Price: $899.99
Quantity: 0
Total Value: $0.0
In stock: false
SKU: LAP0亲手试试
import 'product.dart';
void main() {
// TODO: 创建一个名为 'Laptop'、价格为 999.99、数量为 25 的商品
// TODO: 调用 displayProduct()
// TODO: 打印 "In stock: [isInStock]"
// TODO: 打印 "SKU: [sku]"
// TODO: 尝试将价格设为 -50.0(应被忽略)
// TODO: 将价格设为 899.99(有效修改)
// TODO: 尝试将数量设为 -10(应被忽略)
// TODO: 将数量设为 0(有效修改)
// TODO: 调用 displayProduct()
// TODO: 打印 "In stock: [isInStock]"
// TODO: 打印 "SKU: [sku]"
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器