Classes & Mixins
Constructors, the Dart way
Section titled “Constructors, the Dart way”Dart constructors are richer than most languages, and Flutter uses all of it. The essentials:
class Point { final double x, y;
// Default constructor with `this.` shorthand — assigns fields directly. const Point(this.x, this.y);
// Named constructor — a second way to build one. const Point.origin() : x = 0, y = 0;
// Factory constructor — can return a cached/subtype instance, not just a fresh one. factory Point.fromMap(Map<String, double> m) => Point(m['x']!, m['y']!);}
const p = Point(1, 2); // const construction — canonicalizedfinal o = Point.origin();Three things worth internalizing:
constconstructors (only possible when all fields arefinal) let callers build canonicalized instances — the basis ofconstwidgets.- Named constructors (
Point.origin) give multiple clear ways to construct, instead of overloading. - Factory constructors don’t have to return a new instance — they can return a cached one or a subtype.
factoryis how many Flutter/Dart classes implement singletons or parsing.
Mixins: reuse behavior across unrelated classes
Section titled “Mixins: reuse behavior across unrelated classes”Dart has single inheritance, but mixins let you compose behavior horizontally — add a set of methods/fields to a class without a subclass relationship. This is the Flutter pattern for State classes.
mixin Logger { void log(String msg) => print('[log] $msg');}
mixin Validator { bool isValid(String s) => s.isNotEmpty;}
// Compose several capabilities with `with`:class Form with Logger, Validator { void submit(String value) { if (isValid(value)) log('submitting $value'); }}flowchart TB base["class State"] -->|with| result["your State class"] m1["mixin SingleTickerProviderStateMixin"] -->|with| result m2["mixin WidgetsBindingObserver"] -->|with| result
When you write class _MyState extends State<MyWidget> with SingleTickerProviderStateMixin, you’re mixing in the ability to be a vsync provider for animations — pure horizontal reuse.
Extension methods and enhanced enums
Section titled “Extension methods and enhanced enums”Extension methods add methods to types you don’t own — common for tidy helpers:
extension StringX on String { String get capitalized => isEmpty ? this : this[0].toUpperCase() + substring(1);}'flutter'.capitalized; // 'Flutter'Enhanced enums carry fields and methods, not just names — great for typed, self-describing constants:
enum Status { active('Active', true), archived('Archived', false);
const Status(this.label, this.isVisible); final String label; final bool isVisible;}Status.active.label; // 'Active'