Menu
Coddy logo textTech

Creating Mixins

Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 51 of 110.

Now that you understand what mixins are, let's look at how to create them properly. A mixin is declared using the mixin keyword instead of class.

mixin Logging {
  void log(String message) {
    print('[LOG] $message');
  }
  
  void logError(String error) {
    print('[ERROR] $error');
  }
}

Mixins can contain methods, properties, and even getters and setters - just like classes. However, there's one important rule: mixins cannot have constructors. Since mixins are meant to be "mixed in" rather than instantiated directly, they don't need initialization logic.

mixin Timestamped {
  DateTime createdAt = DateTime.now();
  
  String get formattedTime => createdAt.toString();
  
  void printTimestamp() {
    print('Created at: $formattedTime');
  }
}

class Document with Timestamped {
  String title;
  Document(this.title);
}

void main() {
  var doc = Document('Report');
  doc.printTimestamp();  // Uses mixin's method
  print(doc.createdAt);  // Uses mixin's property
}

When you apply a mixin with with, all its members become part of your class. The class can use them directly, and so can any code that has an instance of that class. This makes mixins a clean way to add reusable functionality without the complexity of inheritance hierarchies.

challenge icon

Challenge

Easy

Let's build a messaging system that showcases how to create mixins with methods, properties, and getters. You'll design a mixin that adds formatting capabilities to different types of messages.

You'll organize your code into two files:

  • messaging.dart: Define your mixin and message classes here:
    • A Formattable mixin that contains:
      • A String prefix property initialized to '>>>'
      • A getter separator that returns ' | '
      • A method format(String text) that returns the string [prefix][separator][text]
      • A method formatBold(String text) that returns **[text]**
    • A TextMessage class that uses the Formattable mixin. Add a String sender property with a constructor. Include a method send(String content) that prints the result of calling format() with [sender]: [content]
    • An AlertMessage class that also uses the Formattable mixin. Add a String level property with a constructor. Include a method alert(String content) that prints the result of calling format() with [[level]] [formatBold(content)]
  • main.dart: Import your messaging file and demonstrate how both message types gain formatting capabilities from the mixin:
    • Create a TextMessage with sender 'Alice'
    • Create an AlertMessage with level 'WARNING'
    • Call send('Hello there!') on the text message
    • Call alert('System overload') on the alert message

Your mixin demonstrates that mixins can contain properties with default values, getters that compute values, and multiple methods that can even call each other. Both message classes gain all of this functionality simply by using the with keyword.

Expected output:

>> | Alice: Hello there!
>>> | [WARNING] **System overload**

Cheat sheet

Mixins are declared using the mixin keyword instead of class:

mixin Logging {
  void log(String message) {
    print('[LOG] $message');
  }
  
  void logError(String error) {
    print('[ERROR] $error');
  }
}

Mixins can contain methods, properties, getters, and setters, but cannot have constructors:

mixin Timestamped {
  DateTime createdAt = DateTime.now();
  
  String get formattedTime => createdAt.toString();
  
  void printTimestamp() {
    print('Created at: $formattedTime');
  }
}

Apply mixins to classes using the with keyword. All mixin members become part of the class:

class Document with Timestamped {
  String title;
  Document(this.title);
}

void main() {
  var doc = Document('Report');
  doc.printTimestamp();  // Uses mixin's method
  print(doc.createdAt);  // Uses mixin's property
}

Try it yourself

import 'messaging.dart';

void main() {
  // TODO: Create a TextMessage with sender 'Alice'
  
  // TODO: Create an AlertMessage with level 'WARNING'
  
  // TODO: Call send('Hello there!') on the text message
  
  // TODO: Call alert('System overload') on the alert message
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming