dart语言中的set与get方法

810 阅读2分钟

在 Dart 语言中,getset 是用于定义 访问器(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}');  // 高度不会被设置为负数
}

说明:

  • widthheightset 访问器,用来设置矩形的宽度和高度,并带有验证逻辑,确保值为正数。
  • rect.width = 10 实际上调用了 set width,类似 rect.height = -5 调用了 set height,但是负数被拒绝。

3. getset 的结合使用

我们可以同时使用 getset 来为属性定义自定义的获取和设置逻辑,这样可以实现对属性的 封装,提高类的健壮性。

示例:getset 结合使用

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}');
}

说明:

  • namesalary 属性通过 getset 方法封装,确保赋值时可以做合法性检查。
  • 当尝试设置无效值(如空字符串或负工资)时,会触发 set 方法中的错误检查逻辑。

4. 注意事项

  • 封装性getset 提供了封装数据的方式,使得类的内部实现可以改变,而不会影响外部代码。你可以在设置器中添加验证逻辑或在访问器中添加缓存逻辑。
  • 私有字段:通常我们使用私有字段(通过在变量前加 _)来保存实际的值,而通过 getset 方法来对这些私有字段进行访问或修改。

总结

  • get 用于定义属性的访问器,使得可以通过属性名称来获取计算后的值。
  • set 用于定义属性的设置器,使得可以通过属性赋值来修改值,并可以添加一些验证或其他逻辑。
  • getset 的结合使用,可以帮助你封装类的内部逻辑,同时提供简洁的外部接口。