Constructors in Depth
Implicit, no args Only if no other constructor is declared Point(this.x, this.y) Creates a new instance Multiple constructors with clear names : x = 0, y = 0 Runs before the body, sets final fields : this(x, 0) Delegates to another constructor const Point(...)
All fields final. Instances can be compile-time constants.
factory Logger(...) Can return existing instances or subtypes. No this access.
Forwards to the superclass constructor Library-private constructor (singletons, utility classes)
Initialization order: initializing formals and the initializer list → the superclass constructor → the constructor body.
class Point {
final double x;
final double y;
// 1. Generative constructor with initializing formals
Point(this.x, this.y);
// 2. Named constructors
Point.origin() : x = 0, y = 0;
Point.fromJson(Map<String, dynamic> json)
: x = (json['x'] as num).toDouble(),
y = (json['y'] as num).toDouble();
// 3. Initializer list with assert
Point.positive(this.x, this.y) : assert(x >= 0 && y >= 0, 'Coordinates must be positive');
// 4. Redirecting constructor
Point.onXAxis(double x) : this(x, 0);
@override
String toString() => 'Point($x, $y)';
}
class ImmutablePoint {
final int x, y;
// 5. Const constructor: enables compile-time constant instances (canonicalized)
const ImmutablePoint(this.x, this.y);
static const origin = ImmutablePoint(0, 0);
}
class Logger {
final String name;
static final Map<String, Logger> _cache = {};
// 6. Factory constructor: can return cached instances or subtypes
factory Logger(String name) => _cache.putIfAbsent(name, () => Logger._internal(name));
Logger._internal(this.name);
}
class Shape {
// Factory returning subtypes
factory Shape(String type) => switch (type) {
'circle' => Circle(1),
…12.1 Singleton Pattern
class AppConfig {
AppConfig._();
static final AppConfig instance = AppConfig._();
String apiUrl = 'https://api.example.com';
}
AppConfig.instance.apiUrl;