在 Dart 语言中,get 和 set 是用于定义 访问器(getters) 和 设置器(setters) 的关键字。它们提供了一种 封装类属性的访问和修改行为 的方式,使得类中的属性可以像直接访问字段一样进行读写,但实际上背后可以包含更多逻辑。
1. get 方法
get 用于定义一个访问器,通常用于返回类中的某个属性值,或者根据一些计算结果返回值。它允许我们像访问普通属性一样调用方法。
get 的语法:
Type get propertyName {
// 返回一个值
}
Type:返回值的类型。propertyName:访问器的名称,通常与实际的字段同名。
示例:定义 get
class Circle {
final double radius;
Circle(this.radius);
// 定义一个 get 方法,用于计算圆的面积
double get area {
return 3.14159 * radius * radius;
}
}
void main() {
Circle circle = Circle(5);
print('Circle area: ${circle.area}'); // 直接通过访问器获取面积
}
说明:
area是一个get访问器,用来计算圆的面积。- 调用时通过
circle.area访问,而不是circle.area(),就像访问普通属性一样。
2. set 方法
set 用于定义一个设置器,通常用于对类中的某个属性赋值。它允许我们像赋值属性一样调用方法,但在背后可以执行更多的逻辑,例如对值进行验证或转换。
set 的语法:
set propertyName(Type value) {
// 设置属性值或执行相关逻辑
}
Type:要设置的值的类型。propertyName:设置器的名称,通常与实际的字段同名。
示例:定义 set
class Rectangle {
double _width = 0;
double _height = 0;
// 访问器,用于获取宽度
double get width => _width;
// 设置器,用于设置宽度,并确保宽度非负
set width(double value) {
if (value > 0) {
_width = value;
} else {
print('Width must be positive');
}
}
// 访问器,用于获取高度
double get height => _height;
// 设置器,用于设置高度,并确保高度非负
set height(double value) {
if (value > 0) {
_height = value;
} else {
print('Height must be positive');
}
}
}
void main() {
Rectangle rect = Rectangle();
rect.width = 10; // 调用 set 方法
rect.height = -5; // 将触发验证逻辑
print('Width: ${rect.width}'); // 调用 get 方法
print('Height: ${rect.height}'); // 高度不会被设置为负数
}
说明:
width和height是set访问器,用来设置矩形的宽度和高度,并带有验证逻辑,确保值为正数。rect.width = 10实际上调用了set width,类似rect.height = -5调用了set height,但是负数被拒绝。
3. get 和 set 的结合使用
我们可以同时使用 get 和 set 来为属性定义自定义的获取和设置逻辑,这样可以实现对属性的 封装,提高类的健壮性。
示例:get 和 set 结合使用
class Employee {
String _name = '';
double _salary = 0;
// 获取员工姓名
String get name => _name;
// 设置员工姓名,确保非空
set name(String value) {
if (value.isNotEmpty) {
_name = value;
} else {
print('Name cannot be empty');
}
}
// 获取员工工资
double get salary => _salary;
// 设置员工工资,确保工资为正数
set salary(double value) {
if (value > 0) {
_salary = value;
} else {
print('Salary must be positive');
}
}
}
void main() {
Employee emp = Employee();
// 设置和获取员工姓名
emp.name = 'Alice';
print('Employee Name: ${emp.name}');
// 尝试设置无效的工资
emp.salary = -5000; // 触发错误检查
emp.salary = 5000; // 设置有效工资
print('Employee Salary: ${emp.salary}');
}
说明:
name和salary属性通过get和set方法封装,确保赋值时可以做合法性检查。- 当尝试设置无效值(如空字符串或负工资)时,会触发
set方法中的错误检查逻辑。
4. 注意事项
- 封装性:
get和set提供了封装数据的方式,使得类的内部实现可以改变,而不会影响外部代码。你可以在设置器中添加验证逻辑或在访问器中添加缓存逻辑。 - 私有字段:通常我们使用私有字段(通过在变量前加
_)来保存实际的值,而通过get和set方法来对这些私有字段进行访问或修改。
总结
get用于定义属性的访问器,使得可以通过属性名称来获取计算后的值。set用于定义属性的设置器,使得可以通过属性赋值来修改值,并可以添加一些验证或其他逻辑。get和set的结合使用,可以帮助你封装类的内部逻辑,同时提供简洁的外部接口。