Everything in Flutter is a class, and widget classes rely on const and named constructors.
A class declares fields, constructors and methods. Every non-nullable field must be initialized before the constructor body runs.
Constructor forms:
- Initializing formals:
Point(this.x, this.y);assigns parameters directly to fields. Named:Person({required this.name, this.age = 0});. - Initializer list after
:runs before the body:Rect(double w) : width = w, height = w * 2;. It can also holdasserts. - Named constructors give alternatives:
Point.origin() : x = 0, y = 0;. - Redirecting:
Point.onX(double x) : this(x, 0);. - const constructors for immutable classes (all fields
final):const Point(this.x, this.y);. Calling withconst Point(1, 2)creates a canonical compile-time constant. - factory constructors may return an existing instance or a subtype, e.g. from a cache or
fromJson.
Getters and setters look like fields: double get area => width * height;. Fields are implicitly given getters (and setters if not final), so you can later replace a field with a getter without changing callers.
Privacy is per library (file), not per class: names starting with _ are private to the file.
Override toString, == and hashCode for value-like classes; otherwise == compares identity. Dart has no new requirement — just call Point(1, 2).
Example
class Point {
final double x;
final double y;
const Point(this.x, this.y);
const Point.origin() : this(0, 0);
factory Point.fromJson(Map<String, dynamic> json) =>
Point((json['x'] as num).toDouble(), (json['y'] as num).toDouble());
double get lengthSquared => x * x + y * y; // a getter
Point operator +(Point o) => Point(x + o.x, y + o.y);
@override
bool operator ==(Object other) => other is Point && other.x == x && other.y == y;
@override
int get hashCode => Object.hash(x, y);
@override
String toString() => 'Point($x, $y)';
}
void main() {
final p = Point(3, 4) + Point.fromJson({'x': 1, 'y': 0});
print(p); // Point(4.0, 4.0)
print(p.lengthSquared); // 32.0
print(Point(1, 1) == Point(1, 1)); // true (custom ==)
print(identical(const Point.origin(), const Point(0, 0))); // true
}Remember
this.xparameters and initializer lists set final fields- Named, const and factory constructors cover most creation needs
_nameis private to the library (file), not the class
Watch out for
- Overriding
==without also overridinghashCode, which breaks Sets and Maps.