Classes, Enums, Extensions
Mixins
Reusing Behavior
mixin declares a reusable block of methods that no class instantiates on its own. A class composes mixins with class C with M1, M2, gaining their methods as if it had declared them. Mixins add behavior, not stored state.
Program
Play the program to call a method that chains through two composed mixins.
mixins.dart
Replay: real traced execution (multi-file project)
mixin Greetable {
String greet(String name) => 'Hello, $name';
}
mixin Loud {
String shout(String msg) => '${msg.toUpperCase()}!';
}
class Bot with Greetable, Loud {
String announce(String name) => shout(greet(name));
}
void main() {
var b = Bot();
print(b.announce('Ada'));
}
b ← Bot instance
13void main() {14 var b = Bot();15 print(b.announce('Ada'));values this stepBot instancebcall ← b.announce('Ada')
14 var b = Bot();15 print(b.announce('Ada'));16}values this stepb.announce('Ada')callBot instancebcalls ← shout(greet('Ada'))
9class Bot with Greetable, Loud {10 String announce(String name) => shout(greet(name));11}values this stepshout(greet('Ada'))callsAdanamereturn value ← Hello, Ada
1mixin Greetable {2 String greet(String name) => 'Hello, $name';3}values this stepHello, Adareturn valueAdanamereturn value ← HELLO, ADA!
5mixin Loud {6 String shout(String msg) => '${msg.toUpperCase()}!';7}values this stepHELLO, ADA!return valueHello, Adamsgreturn value ← HELLO, ADA!
9class Bot with Greetable, Loud {10 String announce(String name) => shout(greet(name));11}values this stepHELLO, ADA!return valueprint(b.announce('Ada'));
14 var b = Bot();15 print(b.announce('Ada'));16}outputHELLO, ADA!
mixin
`mixin Greetable { ... }` declares reusable methods; a mixin cannot be instantiated on its own.
with
`class Bot with Greetable, Loud` composes both mixins so their methods belong to `Bot`.
composition over inheritance
Mixins add behavior without sharing state or forcing a single inheritance chain.