Skip to main content

Menu

System onlineAI Tutorials / 2026

AI Tutorials
Knowledge search

Recent · Popular · Tutorials

  • dart3 tutorials
  • java1 tutorial
  • Javascript3 tutorials
  • Node.js Introduction2 tutorials
  • dartdart · General · In depth
  • JavascriptJavascript · Advanced · In depth
  • JavascriptJavascript · Advanced · Mid
  • JavascriptJavascript · Advanced · Short

Find a tutorial

Tell the assistant what you want to learn. It suggests published chapters.

For example: “I want to learn Rust ownership from the start.” The conversation is kept only in this tab.

0 / 2,000 characters

Enter to send, Shift+Enter for a new line. Do not include personal information.

Chapter 13

Mixins: Sharing Behavior Across Class Trees

So far you have seen two ways classes share code. Inheritance lets one class extend another and reuse its members. Abstract classes define a common shape that subclasses must fill in. Both have a limitation: a class can only have one parent. If you want a class to gain a small, reusable ability—say,
Level: GeneralLength: In depth3 min read

Read at another depth

Mixins: Sharing Behavior Across Class Trees

So far you have seen two ways classes share code. Inheritance lets one class extend another and reuse its members. Abstract classes define a common shape that subclasses must fill in. Both have a limitation: a class can only have one parent. If you want a class to gain a small, reusable ability—say, "can describe itself as text"—inheritance forces awkward choices about where that ability lives in your family tree.

Mixins solve this. A mixin is a way to add a bundle of methods and fields to a class without making it the class's parent. Think of it like attaching a skill to a class. One class can attach several skills from several unrelated sources.

What exactly is a mixin?

A mixin is declared with the mixin keyword. Here is a mixin that gives any class the ability to describe itself:

Code example in dart
mixin Describable {
  String describe();
}

mixin Logger {
  void log(String message) {
    print('[log] $message');
  }
}

To use a mixin, a class combines it with with:

Code example in dart
class Robot with Logger implements Describable {
  final String name;
  Robot(this.name);

  @override
  String describe() => 'A robot named $name';
}

void main() {
  final r = Robot('Rex');
  r.log(r.describe()); // [log] A robot named Rex
}

The Robot class now has a log method it never wrote itself. So do any other classes that mix in Logger. The same mixin can be reused across completely unrelated class trees—a Robot, a BankAccount, and a GameCharacter can all mix in Logger even though they share no parent.

The full recipe

A class declaration can combine a parent and mixins in this order:

Code example in dart
class Vehicle extends Machine with Logger implements Describable {
  ...
}

Read it left to right: extends picks the one parent, with lists mixins, implements lists required shapes. Only the parent can be inherited from; mixins are added on top.

A diagram showing Box extending Container, mixing in Logger and Describable, and implementing Storable, with each contributing members into Box.
100%
One class combining a superclass, two mixins, and an interface.
Show diagram source
classDiagram
    class Container
    class Logger
    class Describable
    class Storable
    class Box
    Container <|-- Box : extends
    Logger -- Box : with
    Describable -- Box : with
    Storable -- Box : implements

Restricting who can use a mixin

Sometimes a mixin only makes sense for classes that already have certain members. For example, a mixin that renames things needs something with a name property. Dart lets a mixin state its requirements with on:

Code example in dart
mixin Shouter on Object {
  String get name;
  void shout() {
    print('${name.toUpperCase()}!!!');
  }
}

Here on Object means any class can use it, but the mixin may use name, so every class mixing it in must supply a name getter. If you write on Animal, only classes that extend (or mix in) Animal can use the mixin, and the mixin can call all of Animal's members.

Order matters when mixins overlap

If two mixins define the same method, the last one in the with list wins. It literally replaces the one before it:

Code example in dart
mixin Quiet {
  void speak() => print('...');
}
mixin Loud {
  void speak() => print('LOUD!');
}

class Person with Quiet, Loud {}
class QuietPerson with Loud, Quiet {}

void main() {
  Person().speak();     // LOUD!
  QuietPerson().speak(); // ...
}

This is worth remembering: mixin order is not decoration, it is behavior. When you read code with multiple mixins, check them right to left to see which versions of overlapping members survive.

Mixins can also be abstract

A mixin can mix concrete methods and abstract ones—methods it declares but does not define. Any class using the mixin must supply the abstract parts. That is what made Describable work earlier: it declared describe() with no body, and Robot provided it.

When to choose a mixin

Use this decision guide:

SituationBetter choice
A true "is-a" relationship with shared state and identityInheritance (`extends`)
A small reusable ability used by unrelated classesMixin (`with`)
Just a contract, no code at allAbstract class or `implements`
Adding behavior to a class you cannot modifyMixin, if you own the hierarchy it restricts to

A good rule of thumb: if you find yourself creating a base class that holds one method used by many unrelated subclasses, it probably wants to be a mixin.

Gotchas to keep in mind

  • Hidden dependencies. A mixin that calls members it does not define (like name above) creates an invisible requirement. Document those members, or use on to make the requirement explicit.
  • State in mixins. Mixins can hold fields, but shared mutable fields across many classes can cause surprising bugs. Keep mixins stateless when you can.
  • Too many mixins. A class with six mixins is hard to reason about. Two or three that each do one clear job is a healthy ceiling.
  • No constructors. Mixins cannot have constructors. They are attached, not built.

Where you will see mixins in real Dart

The standard library uses mixins heavily. Iterable helpers, Comparable-style classes, and many Flutter widgets (such as SingleTickerProviderStateMixin) are mixins. Learning to read a with clause is essential for reading real Dart and Flutter code.

Try it yourself

Code example in dart
mixin Greeter {
  String get name;
  void greet() => print('Hello, $name!');
}

class Dog with Greeter {
  @override
  String get name => 'Rex';
}

void main() {
  Dog().greet(); // Hello, Rex!
}

Change name and watch the output change. Then add a second mixin that also defines greet and see which one wins.

Exercise

A class is declared as class C with A, B { } and both A and B define a method called run(). Which version does C use?

Show answer

The one from B, because the last mixin in the with list replaces earlier ones when they define the same member.

Exercise

Why would you write mixin Swimmer on Animal instead of just mixin Swimmer?

Show answer

The on clause restricts the mixin to classes related to Animal and lets the mixin use Animal's members. It makes the mixin's hidden requirements explicit and prevents misuse on unrelated classes.

Spotted a mistake, or code that does not work?

Report an issue

Chapter: Mixins: Sharing Behavior Across Class Trees

0 / 2,000 characters

Plain text, for example: the second code sample does not compile. Do not include personal information.

You can't do that