Summary: In this tutorial, you’ll learn about Dart getters and setters and how to use them to provide access to private fields.
Introduction to the Dart getter & setter #
Let’s consider the following example:
First, define a class Circle in the circle.dart library:
class Circle {
double _radius = 0;
Circle(double radius) {
if (radius >= 0) {
_radius = radius;
}
}
}Code language: Dart (dart)The Circle class has a private field called _radius. In the constructor, we check the radius before assigning it to the _radius private field.
Second, use the Circle class in the main.dart file:
import 'circle.dart';
void main() {
var circle = Circle(10);
}Code language: Dart (dart)An issue with the Circle class is that you cannot access or modify the _radius private field from the outside of the class.
To fix this, you can make the _radius a property. However, to do so, the caller of the class may do this:
import 'circle.dart';
void main() {
var circle = Circle(radius: 10);
circle.radius = -10;
}Code language: Dart (dart)This is invalid because the radius should not be negative. To resolve this, Dart offers special methods called setters.
Setters #
A setter starts with the void keyword, followed by the set keyword, and takes a parameter that you can assign to the private field.
For example, the following defines a setter that assigns a value to the _radius field:
void set radius(double value) {
if (value >= 0) {
_radius = value;
}
print('Setter was called');
}Code language: Dart (dart)The radius setter checks if the value is greater than or equal to zero before assigning it to the _radius private field. The print() statement is for illustration purposes.
The following shows the updated version of the Circle class:
class Circle {
double _radius = 0;
Circle(double radius) {
if (radius >= 0) {
_radius = radius;
}
}
void set radius(double value) {
print('Setter was called.');
if (value >= 0) {
_radius = value;
print('The _radius is $_radius.');
}
}
}Code language: Dart (dart)When you assign a value to the radius, Dart will automatically call the radius setter. For example:
import 'circle.dart';
void main() {
var circle = Circle(10);
circle.radius = 100;
}Code language: Dart (dart)Output:
Setter was called.
The _radius is 100.0.Code language: Dart (dart)The following code calls the setter that assigns 100 to the _radius field:
circle.radius = 100;Code language: Dart (dart)Since the setter has a validation logic check, you can reuse it in the constructor of the class as follows:
class Circle {
double _radius = 0;
Circle(double radius) {
this.radius = radius;
}
void set radius(double value) {
if (value >= 0) {
_radius = value;
}
}
}Code language: Dart (dart)Getters #
Now, you can use the radius setter to check and set a value for the _radius private field. But you cannot read from it.
The following will result in an error:
import 'circle.dart';
void main() {
var circle = Circle(10);
circle.radius = 100;
// error
print(circle.radius);
}Code language: Dart (dart)To access the radius like above, you need to use a getter.
Like a setter, a getter is a special method. A getter uses the get keyword before a property name and returns a value.
For example, the following defines the radius getter:
double get radius {
return _radius;
}Code language: Dart (dart)Since this getter has only one line of code, you can use the arrow syntax to make it more concise:
double get radius => _radius;Code language: Dart (dart)The following shows the updated version of the Circle class with a getter and setter:
class Circle {
double _radius = 0;
Circle(double radius) {
this.radius = radius;
}
void set radius(double value) {
if (value >= 0) {
_radius = value;
}
}
double get radius => _radius;
}Code language: Dart (dart)Now, the main.dart will run successfully:
import 'circle.dart';
void main() {
var circle = Circle(10);
circle.radius = 100;
// success
print(circle.radius);
}Code language: Dart (dart)Computed property #
By using a getter, you can define a computed property. A computed property is not backed by a dedicated field but instead is computed when called.
The following example uses a getter to define the area as the computed property of the Circle class:
double get area => radius * radius * 3.14;Code language: Dart (dart)By doing this, you can get the area of the circle using this syntax:
circle.area;Code language: Dart (dart)The following shows the complete Circle class:
class Circle {
double _radius = 0;
Circle(double radius) {
this.radius = radius;
}
void set radius(double value) {
if (value >= 0) {
_radius = value;
}
}
double get radius => _radius;
double get area => radius * radius * 3.14;
}Code language: Dart (dart)And main.dart file:
import 'circle.dart';
void main() {
var circle = Circle(10);
circle.radius = 100;
print('The area is ${circle.area}');
}Code language: Dart (dart)Output:
The area is 31400.0Code language: Dart (dart)Summary #
- Use getters/setters to provide access to private fields.
- A computed property is not based on a dedicated field but is computed when called.