1. 封装的概念
在 Dart 中,封装是面向对象编程的一个重要特性。它主要是指将数据(变量)和操作这些数据的方法(函数)组合在一个类中,并对外部隐藏数据的具体实现细节,只通过定义好的公共方法来访问和修改数据。这样可以提高代码的安全性和可维护性。
2. 如何在Dart中实现封装
**Dart 不支持 public、private 和 protected 等关键字。Dart 使用 _ (下划线)将属性或方法设为私有。封装发生在库级别,而不是类级别。
- 使用下划线(_) 将类属性声明为
私有
。 - 提供公共的
getter
和setter
方法来访问和更新私有属性的值。
3. getter 和 setter
Getter 和 setter 方法用于访问和更新私有属性的值.
- Getter 方法用于访问 私有属性 的值。
- Setter 方法用于更新 私有属性 的值。
4. 场景1:温度转换
class Temperature {
double _celsius;
Temperature.celsius(this._celsius);
// 获取摄氏度
double get celsius => _celsius;
// 设置摄氏度
set celsius(double value) {
_celsius = value;
}
// 获取华氏度
double get fahrenheit => _celsius * 9 / 5 + 32;
// 设置华氏度
set fahrenheit(double value) {
_celsius = (value - 32) * 5 / 9;
}
}
void main() {
var temp = Temperature.celsius(25);
print(temp.fahrenheit); // 77.0
temp.fahrenheit = 77;
print(temp.celsius); // 25.0
}
描述:
- 类中有一个私有字段
_celsius
,用于存储摄氏度值。 - 构造函数
Temperature.celsius
允许创建一个Temperature
对象时直接传入摄氏度值。 - 提供了一个名为
celsius
的getter方法,用于获取当前对象的摄氏度值。 - 提供了一个名为
celsius
的setter方法,允许设置当前对象的摄氏度值。 - 提供了一个名为
fahrenheit
的getter方法,用于将当前对象的摄氏度值转换为华氏度并返回。 - 提供了一个名为
fahrenheit
的setter方法,允许通过设置华氏度值来间接设置摄氏度值。在setter方法内部,华氏度值会被转换为摄氏度,并存储在_celsius
字段中。
5. 场景2: 数据校验
假设一个场景,是给一个商品类实例化的时候,确保商品的价格不能为负数,那么我们就可以使用setter, 来进行数据的校验。
class Product {
String name;
double _price;
Product(this.name, this._price);
// 获取库存数量
double get price => _price;
// 设置库存数量,并进行验证
set price(double value) {
if (value < 0) {
throw Exception('${this.name}不能为负数。');
}
_price = value;
}
}
void main() {
var item = Product("铅笔", 10);
// item.price = 15;
// print(item.price); // 15
// 下面的代码会抛出异常
item.price = -5;
}
}
报错:
6. 总结
在Dart语言中,封装是一种重要的面向对象编程特性,它通过将数据(属性)和操作数据的方法(函数)封装在类内部,并控制对这些数据的访问方式,来提高代码的安全性和可维护性。以下是关于Dart中封装、getter和setter的一些关键点:
封装的好处:
- 数据保护:通过将属性设置为私有,可以防止外部直接访问和修改类的内部状态。
- 抽象:对外提供简单的接口,隐藏复杂的实现细节。
- 维护性:由于外部只能通过定义好的接口与对象交互,因此在修改内部实现时,对其他代码的影响较小。
Dart中的封装实现:
- 使用下划线(_)前缀来标识私有属性或方法。
- 提供公共的getter和setter方法来控制私有属性的访问和修改。
Getter和Setter的作用:
-
Getter:
- 用于安全地获取私有属性的值。
- 可以包含额外的逻辑,如计算属性。
-
Setter:
- 用于安全地设置私有属性的值。
- 可以包含数据验证逻辑,确保数据的一致性和有效性。
应用场景:
-
场景1:温度转换:
- 使用getter和setter来实现摄氏度和华氏度之间的转换。
-
场景2:数据校验:
- 在setter中添加逻辑,确保商品价格不为负数,从而保护数据的一致性。
总结:
- Getter和Setter是Dart中实现封装的强大工具,它们不仅允许对私有属性进行安全的访问和修改,还能在访问和修改过程中加入额外的逻辑。
- 通过使用getter和setter,可以确保类的内部状态始终处于有效和一致的状态,从而提高代码的健壮性。
- 在实际开发中,应当根据具体情况合理使用getter和setter,以实现数据保护、逻辑封装和代码优化。