getter和setter如何在Dart中更改属性?

时间:2014-12-29 05:39:18

标签: dart

我正在努力解决Dart中的getter和setter概念,我读的越多,我就无法理解其根本目的。以下面的代码为例:

main() {
    Car car = new Car();
    car.doors = 44;
    print(car.doors);  // 44
}
class Car {
    int doors = 4;
}

后来,我决定将“门”变成私有变量,所以我做了以下几点:

main() {
    Car car = new Car();
    car.doors = 44;
    print(car.doors);  // 44
}
class Car {
    int _doors = 4;
    int get doors => _doors;
    set doors(int numberOfDoors) => _doors = numberOfDoors;
}

根据代码,_doors现在是一个私有变量,因此我无法在main()中访问它。但是,通过操纵doors,我可以间接地改变_doors的值,这是我认为我想首先通过将其作为私有变量来防止的。那么,如果您仍然可以间接操纵它,那么将以前的公共变量变为私有变量的目的是什么?而且,getter和setter如何改变这些变量的属性呢?我试图理解基本概念,因为如果没有这个概念,我就不会理解使用吸气剂和固定器的方式或原因。

3 个答案:

答案 0 :(得分:37)

Dart中的实例变量具有隐式getter和setter。因此,对于您的示例代码,它将以完全相同的方式运行,因为您所做的就是从隐式getter和setter更改为显式getter和setter。

显式getter和setter的值是,如果你不想要,你不需要定义它们。例如,我们可以将您的示例更改为仅定义getter:

main() {
    Car car = new Car();
    print(car.doors);  // 4
    car.doors = 6; // Won't work since no doors setter is defined
}

class Car {
    int _doors = 4;
    int get doors => _doors;
}

此外,您还可以在getter或setter中添加额外的逻辑,而这些逻辑不会出现在隐式getter或setter中:

class Car {
    int _doors = 4;
    int get doors => _doors;
    set doors(int numberOfDoors) {
      if(numberOfDoors >= 2 && numberOfDoors <= 6) {
        _doors = numberOfDoors;
      }
    }
}

答案 1 :(得分:1)

getter和setter函数允许我们使类出现以获得属性,而不会声明显式属性(在您的情况下为_doors)。可以从其他属性计算属性值。

getter和setter允许我们在获取或设置属性时执行任意代码。

省略一个setter使该属性不可变。

抽象类可以声明没有实体的getter和setter作为必需类接口的一部分。

答案 2 :(得分:0)

当您需要对属性进行比简单字段允许的更多控制时,您可以定义 getter 和 setter。

例如,您可以确保属性的值有效:

class MyClass {
  int _aProperty = 0;

  int get aProperty => _aProperty;

  set aProperty(int value) {
    if (value >= 0) {
      _aProperty = value;
    }
  }
}

您还可以使用 getter 来定义计算属性:

class MyClass {
  List<int> _values = [];

  void addValue(int value) {
    _values.add(value);
  }

  // A computed property.
  int get count {
    return _values.length;
  }
}

代码示例

假设您有一个购物车类,其中包含价格的私有 List<double>。添加以下内容:

  • 名为 total 的 getter 返回价格的总和

  • 一个用新列表替换列表的 setter,只要新列表不包含任何负价格(在这种情况下,setter 应该抛出一个 InvalidPriceException)。

    lass InvalidPriceException {}

    class ShoppingCart { 列出_prices = [];

    double get total => _prices.fold(0, (e, t) => e + t);
    
    set prices(List<double> value) {
      if (value.any((p) => p < 0)) {
        throw InvalidPriceException();
      }