How do getters and setters change properties in Dart?

Dart

Dart Problem Overview


I am struggling with the concept of getters and setters in Dart, and the more I read, the more I cannot grasp the underlying purpose. Take for example the following code:

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

Later, I decide to make “doors” a private variable, so I do the following:

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

According to the code, _doors is now a private variable, and so I cannot access it in main(). However, by manipulating doors, I can indirectly change the value of _doors, which is what I thought I wanted to prevent in the first place by making it a private variable. So what is the purpose of making a previously public variable into a private one, if you can still indirectly manipulate it? And, how are getters and setters even working to change the properties of these variables? I am trying to understand the fundamental concept, because without that, I don't understand how or why getters and setters are used.

Dart Solutions


Solution 1 - Dart

Instance variables in Dart have implicit getters and setters. So for your example code, it will operate in exactly the same way, since all you have done is changed from an implicit getter and setter to an explicit getter and setter.

The value of explicit getters and setters is that you don't need to define both if you don't want. For instance we can change your example to only define a 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;
}

Additionally, you can also add extra logic in a getter or setter that you don't get in an implicit getter or setter:

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

Solution 2 - Dart

The getter and setter functions allow us to make the class appear to have a property, without a explicit property being declared (_doors in your case). The property value may be calculated from other properties.

The getters and setters allow us to execute arbitrary code when the property is get or set.

Omitting a setter makes the property immutable.

An abstract class may declare getters and setters without bodies as part of a required class interface.

Solution 3 - Dart

You can define getters and setters whenever you need more control over a property than a simple field allows.

For example, you can make sure a property’s value is valid:

class MyClass {
  int _aProperty = 0;

  int get aProperty => _aProperty;

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

You can also use a getter to define a computed property:

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

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

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

Code example

Imagine you have a shopping cart class that keeps a private List<double> of prices. Add the following:

  • A getter called total returns the sum of the prices

  • A setter that replaces the list with a new one, as long as the new list doesn’t contain any negative prices (in which case the setter should throw an InvalidPriceException).

    lass InvalidPriceException {}

    class ShoppingCart { List _prices = [];

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrichalotView Question on Stackoverflow
Solution 1 - DartPixel ElephantView Answer on Stackoverflow
Solution 2 - DartArgenti ApparatusView Answer on Stackoverflow
Solution 3 - DartParesh MangukiyaView Answer on Stackoverflow