Skip to content
AgileLogics
5 min read

Mixins

Prerequisites: Interfaces and implements

A mixin is a bundle of fields and methods that can be added to any class with with. It lets unrelated classes share behavior without a common superclass.

Example

mixin Greetable {
  String get name;
  String greet() => "Hi, I'm $name";
}

mixin Timestamped {
  DateTime createdAt = DateTime.utc(2025, 1, 15);
  String get createdLabel => 'created ${createdAt.year}-${createdAt.month}-${createdAt.day}';
}

class User with Greetable, Timestamped {
  @override
  final String name;
  User(this.name);
}

class Robot with Greetable {
  @override
  String get name => 'R2';
}

void main() {
  final user = User('Ada');
  print(user.greet());
  print(user.createdLabel);
  print(Robot().greet());
}

Expected output

Hi, I'm Ada
created 2025-1-15
Hi, I'm R2
  • mixin Greetable defines reusable behavior. It declares an abstract name getter, which each class must provide.
  • class User with Greetable, Timestamped mixes both in. User and Robot share greet() without being related.

Restricting a mixin

on limits a mixin to subclasses of a particular type, so it can call that type's methods:

class Animal {
  void move() => print('moving');
}

mixin Swimmer on Animal {
  void swim() {
    move();
    print('swimming');
  }
}

class Duck extends Animal with Swimmer {}

void main() {
  Duck().swim();
}
moving
swimming

In Flutter

You'll meet mixins early in Flutter: animated widgets use with SingleTickerProviderStateMixin to get animation timing.

Common mistakes

  • Putting too much into a mixin. Mixins that rely on many things from the class using them are hard to understand. Keep them small.