What are Mixins?
Mixins provide a way to reuse code across multiple class hierarchies without inheritance. They let you "mix in" capabilities into a class. Since Dart only supports single inheritance, mixins solve the diamond problem elegantly.
Defining a Mixin
mixin Swimmable {
void swim() => print('$runtimeType is swimming!');
}
mixin Flyable {
void fly() => print('$runtimeType is flying!');
}
mixin Runnable {
void run() => print('$runtimeType is running!');
}
Using Mixins with with
class Duck extends Animal with Swimmable, Flyable, Runnable {
Duck(String name) : super(name);
}
class Penguin extends Animal with Swimmable, Runnable {
Penguin(String name) : super(name);
}
void main() {
var duck = Duck('Donald');
duck.swim(); // Duck is swimming!
duck.fly(); // Duck is flying!
duck.run(); // Duck is running!
var penguin = Penguin('Tux');
penguin.swim(); // Penguin is swimming!
penguin.run(); // Penguin is running!
// penguin.fly(); ← ERROR: Penguin doesn't have Flyable
}
Restricting Mixins with on
Use on to restrict a mixin to specific parent classes:
mixin Logger on Animal {
void log(String msg) => print('[$${name}] $msg');
}
class Robot extends Animal with Logger {
Robot(String name) : super(name);
}
var r = Robot('R2D2');
r.log('System ready'); // [R2D2] System ready
Full Example
mixin Serializable {
Map<String, dynamic> toJson();
String serialize() => toJson().toString();
}
mixin Validatable {
bool validate();
void assertValid() {
if (!validate()) throw Exception('Validation failed for $runtimeType');
}
}
class User with Serializable, Validatable {
String name;
String email;
User(this.name, this.email);
@override
Map<String, dynamic> toJson() => {'name': name, 'email': email};
@override
bool validate() => name.isNotEmpty && email.contains('@');
}
void main() {
var user = User('Alice', 'alice@example.com');
user.assertValid();
print(user.serialize());
}
Output:{name: Alice, email: alice@example.com}
🧠 Quiz
1. What keyword applies a mixin to a class?
- A) extends
- B) implements
- C) with ✅
- D) include
2. What problem do mixins solve that single inheritance cannot?
- A) Memory management
- B) Reusing behavior from multiple sources without multiple inheritance ✅
- C) Performance
- D) Null safety
Summary
Mixins provide reusable behavior that can be applied to any class using with. Define mixins with the mixin keyword. Apply multiple mixins to a single class. Use on to restrict which classes can use a mixin. Mixins solve the limitation of single inheritance by enabling mixin composition.