【问题标题】:How do getters and setters change properties in Dart?getter 和 setter 如何改变 Dart 中的属性?
【发布时间】:2015-02-25 08:20:20
【问题描述】:

我在 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 是如何改变这些变量的属性的呢?我试图理解基本概念,因为没有它,我不明白如何或为什么使用 getter 和 setter。

【问题讨论】:

    标签: dart


    【解决方案1】:

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

    【讨论】:

    • 我认为关于附加逻辑的最后一点是关键部分。通过将变量设为私有,您需要通过您的设置器进行任何更改,这会强制运行额外的逻辑(可以考虑未将设置器定义为阻止所有设置的特定类型的设置器逻辑的情况)。
    • 总而言之,getter 和 setter 只是用来覆盖默认的 getter 和 setter,从而提供更大的灵活性。这可能有用的情况:1)当您希望实例变量具有不同的 getter(重新分配变量)、setter(分配值)或两者时。 2) 如果你想在赋值中添加逻辑,setter 可以这样做。在我的示例中,我应该删除“set”行。这将重新分配门以等于 _doors 的值(并且不会破坏向后兼容性),但由于门无法更改,_doors 不会受到影响,从而使 _doors 真正私有。谢谢。
    • 如何在构造函数中调用 setter(例如,我们可以执行 myCar = Car(doors: 4) 之类的操作?
    【解决方案2】:

    getter 和 setter 函数允许我们使类看起来具有属性,而无需声明显式属性(在您的情况下为_doors)。属性值可以从其他属性中计算出来。

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

    省略 setter 使属性不可变。

    抽象类可以将没有主体的 getter 和 setter 声明为所需类接口的一部分。

    【讨论】:

      【解决方案3】:

      当您需要对属性进行比简单字段允许的更多控制时,您可以定义 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&lt;double&gt; 价格。添加以下内容:

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

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

        类 InvalidPriceException {}

        类购物车{ 列出_prices = [];

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-15
        • 2018-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多