Skip to content

OOP: Mixins - Code Reuse Tool

What are Mixins?

Mixins are a way to reuse code in multiple class hierarchies without using inheritance.

Basic Mixin

dart
mixin Flyable {
  void fly() {
    print('Flying!');
  }
}

mixin Swimmable {
  void swim() {
    print('Swimming!');
  }
}

class Bird with Flyable {}

class Fish with Swimmable {}

class Duck with Flyable, Swimmable {}

void main() {
  Bird().fly();        // Flying!
  Fish().swim();       // Swimming!
  
  var duck = Duck();
  duck.fly();          // Flying!
  duck.swim();         // Swimming!
}

Mixin with State

dart
mixin Musical {
  bool isPlaying = false;
  
  void play() {
    isPlaying = true;
    print('Playing music');
  }
  
  void stop() {
    isPlaying = false;
    print('Music stopped');
  }
}

class Smartphone with Musical {
  String brand;
  
  Smartphone(this.brand);
}

void main() {
  var phone = Smartphone('iPhone');
  phone.play();   // Playing music
  phone.stop();   // Music stopped
}

Mixin with on Clause

Restrict which classes can use the mixin:

dart
class Animal {
  void breathe() => print('Breathing');
}

mixin Flyable on Animal {
  void fly() {
    breathe();  // Can use Animal methods
    print('Flying');
  }
}

class Bird extends Animal with Flyable {}

// class Plane with Flyable {}  // Error: Plane must extend Animal

void main() {
  Bird().fly();
}

Complete Example

dart
abstract class Vehicle {
  void move();
}

mixin Electric {
  int batteryLevel = 100;
  
  void charge() {
    batteryLevel = 100;
    print('Fully charged');
  }
  
  void useBattery(int amount) {
    batteryLevel -= amount;
    print('Battery: $batteryLevel%');
  }
}

mixin GPS {
  void navigate(String destination) {
    print('Navigating to $destination');
  }
}

class ElectricCar extends Vehicle with Electric, GPS {
  @override
  void move() {
    useBattery(10);
    print('Car is moving');
  }
}

void main() {
  var car = ElectricCar();
  car.move();                    // Battery: 90%, Car is moving
  car.navigate('Home');          // Navigating to Home
  car.charge();                  // Fully charged
}

Next Steps

Content is for learning and research only.