Summary: in this tutorial, you’ll learn how to create Dart private fields of a class by prefixing variables with an underscore (_
).
Introduction to the Dart private fields
When you define a property for a class, you can access it from the outside of a class. The accessibility of the property is public.
To make the property private, you need to prefix its name with an underscore (_
):
type _privateVariable;
Code language: Dart (dart)
Note that a variable of a class is generally called a field. However, if it can be accessed from outside of a class, it is called a property.
The following example defines the Point
class with the private fields _x
and _y
:
class Point {
int _x = 0;
int _y = 0;
Point({int x = 0, int y = 0}) {
this._x = x;
this._y = y;
}
show() {
print('Point(x=$_x,y=$_y)');
}
}
void main() {
var p1 = Point(x: 10, y: 20);
p1.show();
}
Code language: Dart (dart)
Output:
Point(x=10,y=20)
Code language: Dart (dart)
How it works.
First, define _x
and _y
as the private properties for the Point
class:
int _x = 0;
int _y = 0;
Code language: Dart (dart)
Second, initialize the _x
and _y
in the constructor:
Point({int x = 0, int y = 0}) {
this._x = x;
this._y = y;
}
Code language: Dart (dart)
In this example, we define _x
and _y
as the private field for the Point
class. The constructor initializes _x
and _y
with the corresponding arguments.
Third, display the _x
and _y
in the show()
method:
show() {
print('Point(x=$_x,y=$_y)');
}
Code language: Dart (dart)
Finally, create a new instance of the Point
class and call the show()
method:
void main() {
var p1 = Point(x: 10, y: 20);
p1.show();
}
Code language: Dart (dart)
The following example attempts to access the _x
and _y
private fields in the main()
function:
void main() {
var p1 = Point(x: 10, y: 20);
p1.show();
p1._x = 100;
p1._y = 200;
p1.show();
}
Code language: Dart (dart)
Output:
Point(x=10,y=20)
Point(x=100,y=200)
Code language: Dart (dart)
The code works in a way that you may not expect because _x
and _y
fields are supposed to be private.
In Dart, privacy is at the library level rather than the class level. Adding an underscore to a variable makes it library private not class private.
For now, you can understand that a library is simply a Dart file. Because both the Point
class and the
function are on the same file, they’re in the same library. Therefore, the main()
function can access the private fields of the main()
Point
class.
To prevent other functions from accessing the private fields of the Point
class, you need to create a new library and place the class in it.
First, create a new file called point.dart
and add the Point
class to the file:
class Point {
int _x = 0;
int _y = 0;
Point({int x = 0, int y = 0}) {
this._x = x;
this._y = y;
}
show() {
print('Point(x=$_x,y=$_y)');
}
}
Code language: Dart (dart)
Second, import the point.dart
library into the main.dart
so that you can reference the Point
class:
import 'point.dart';
void main() {
var p1 = Point(x: 10, y: 20);
p1.show();
}
Code language: Dart (dart)
If you compile and run the program, it should work as expected.
Third, if you attempt to access the _x
and _y
properties from the main.dart
, you’ll get an error:
import 'point.dart';
void main() {
var p1 = Point(x: 10, y: 20);
p1.show();
// errors
p1._x = 100;
p1._y = 200;
}
Code language: Dart (dart)
Initializer list
If you use private fields, you may find a problem with an unnamed constructor. For example, the following code causes an error:
class Point {
int _x = 0;
int _y = 0;
Point({this._x = 0, this._y = 0});
show() {
print('Point(x=$_x,y=$_y)');
}
}
Code language: Dart (dart)
To fix it, you need to use something calls an initializer list. For example:
class Point {
int _x = 0;
int _y = 0;
Point({int x = 0, int y = 0})
: _x = x,
_y = y;
show() {
print('Point(x=$_x,y=$_y)');
}
}
Code language: Dart (dart)
In this example, the comma-separated list that appears after the semicolon (:
) is called an initializer list.
Summary
- Add underscore (
_
) to fields to make them private at the library level rather than the class level. - A library is a source code file in Dart.
- Use an initializer list in the unnamed constructor to initialize private fields.