Getters and setters are special methods that provide explicit read and write access to an object's properties.
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 a special method called setter.
Setters
A setter starts with 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:
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;
}
}
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;
}
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.
As 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;
}
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:
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;
}
set radius(double value) {
if (value >= 0) {
_radius = value;
}
}
double get radius => _radius;
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.0
Summary
Use getter/setter to provide access to a private field.
A computed property is not based on a dedicated field but is computed when called.