How to use Getters and Setters in Dart

In Flutter, encapsulation is an important concept that helps maintain clean and organized code by hiding the internal details of a class. It ensures that the implementation details are hidden and that only the necessary information and functionality are exposed. Getters and setters play an essential role in achieving encapsulation. In this article, we will go over getters and setters in Flutter, exploring their benefits and use cases.

The Basics

Getters and setters are special functions that control how you can access and modify the data stored in a class. They help you organize and protect the data by hiding the details inside the class. With getters and setters, you have the power to determine how the data is read and changed, making sure it is valid, calculating additional properties, and keeping the data consistent.

Getters

A getter is a function that returns the value of a property. It is defined using the get keyword followed by the name of the getter. Getters do not take any parameters and return a value of the specified type. Before returning the value, you are free to add additional logic or calculations.

Here is an example of a getter:

class Rectangle {
  double width = 0;

  double get getWidth {
    // Additional logic or calculations if needed
    return width;
  }
}

In this code snippet, we created a class called Rectangle with a property called width. Inside the getter getWidth, we return the widthproperty. To access this property, we can instantiate the Rectangle and access it like any other property.

In the following code example, you can see the difference between accessing the myField property directly and through the getter:

void main() {
  print(Rectangle().width);
  print(Rectangle().getWidth);
}

Both statements will print 0.0.

Setters

A setter is a function that changes the value of a property. You use the set keyword followed by the name of the setter. The setter takes one input, which is the new value you want to assign to the field. Setters allow you to check if the value is valid or perform extra actions before actually setting it.

Here is an example of a setter:

class Rectangle {
  double width = 0;

  void set setWidth(double value) {
    // Data validation or additional actions if needed
    width = value;
  }
}

In this code snippet, we created a class called Rectangle with a property called width. Inside the setter setWidth, we set the width property. To use the getter we create an instance of our class, then access the setter on our instance and set it to 50 by using the = operator.

In the following code example, you can see the difference between accessing the width property directly and through the setter:

void main() {
  Rectangle rectangle = Rectangle();
  
  rectangle.width = 40;
  print(rectangle.width);

  rectangle.setWidth = 50;
  print(rectangle.width);
}

The first print statement will print 40.0 and the second will print 50.0.

Private fields

To keep the fields of a class separate and hidden, it is common to add an underscore _ at the beginning of their names. This makes them private and only accessible within the class itself. By marking the fields as private, you make sure that external code can only access or change them using the getters and setters functions.

See the example below:

class Rectangle {
  double _width = 0;

  double get width {
    return _width;
  }

  void set width(double value) {
    _width = value;
  }
}

In this code snippet, we changed the width variable to private by prefixing the variable with an underscore _. Now we can no longer access the _width directly only via the getter and setter. In both the getter and setter, we are using the private field now. As you can see we changed the name of the getter and setter to width. This makes it very easy to understand which field the getter and setter present.

When we run our main function with the following code:

void main() {
  Rectangle rectangle = Rectangle();

  rectangle.width = 50;
  
  print(rectangle.width);
}

We will still be able to change and retrieve the value of the _width property. However, not directly access it using Rectangle()._width.

In Dart, private properties are limited to the code files where they are declared. This means that if a property has an underscore _ at the beginning of its name, it can only be accessed within the same code file.

Usage and Benefits

By using getters and setters, you can achieve several benefits in your Flutter code:

  • Encapsulation and data protection: Getters and setters allow you to hide the internal representation of data and provide controlled access to class fields.
  • Data validation and consistency: Setters enable you to enforce data validation rules before assigning a value, ensuring data consistency.
class Rectangle {
  double _width = 0;

  set width(double value) {
    if (value > 0) _width = value;
  }
}
  • Computed properties: Getters can calculate properties based on other fields or calculations.
class Rectangle {
  double _width = 0;
  double _height = 0;

  double get area {
    return _width * _height;
  }
}
  • Flexibility for future modifications: Using getters and setters allows you to modify the internal implementation without affecting external code, promoting code maintainability.
  • Code organization and readability: Getters and setters enhance code readability and organization.

Conclusion

In Flutter, getters and setters help you control how you access and change class properties. They make your code more organized and encapsulated. By using getters and setters effectively in your Flutter projects, you can validate data, calculate additional properties, and make your code more flexible for future changes.

Tijn van den Eijnde
Tijn van den Eijnde
Articles: 87

Leave a Reply

Your email address will not be published. Required fields are marked *