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
EasyLet'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
Formattablemixin that contains:- A
String prefixproperty initialized to'>>>' - A getter
separatorthat returns' | ' - A method
format(String text)that returns the string[prefix][separator][text] - A method
formatBold(String text)that returns**[text]**
- A
- A
TextMessageclass that uses theFormattablemixin. Add aString senderproperty with a constructor. Include a methodsend(String content)that prints the result of callingformat()with[sender]: [content] - An
AlertMessageclass that also uses theFormattablemixin. Add aString levelproperty with a constructor. Include a methodalert(String content)that prints the result of callingformat()with[[level]] [formatBold(content)]
- A
main.dart: Import your messaging file and demonstrate how both message types gain formatting capabilities from the mixin:- Create a
TextMessagewith sender'Alice' - Create an
AlertMessagewith level'WARNING' - Call
send('Hello there!')on the text message - Call
alert('System overload')on the alert message
- Create a
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
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesLibraries & ImportsIntroduction to OOPClasses vs ObjectsThe this KeywordMethodsInstance VariablesConstructor BasicsRecap - Simple Calculator4Null Safety
Intro to Null SafetyNullable vs Non-NullableThe ? and ! OperatorsLate Keyword & Null SafetyNull-Aware OperatorsNull Safety in ClassesRecap - User Profile System7Abstract Classes & Interfaces
Abstract ClassesAbstract MethodsInterfaces in DartImplicit InterfacesImplementing vs ExtendingMultiple InterfacesRecap - Shape Calculator10Collections & Generics
List, Set, Map OverviewType-Safe CollectionsGeneric ClassesGeneric MethodsGeneric ConstraintsIterable & IteratorRecap - Generic Storage13Advanced OOP Concepts
Composition vs InheritanceExtension MethodsCallable ClassesSealed Classes (Dart 3)Records (Dart 3)Patterns & Matching (3.0)Enums with Methods16Project: Library Management
Project OverviewBook and User Classes2Constructors in Dart
Default ConstructorNamed ConstructorsInitializer ListsConstant ConstructorsFactory ConstructorsRedirecting ConstructorsRecap - Shape Builder5Encapsulation
Public vs Private MembersThe _ Prefix ConventionLibrary-Level PrivacyGetters & Setters DepthInformation HidingRecap - Student Records8Mixins
Introduction to MixinsCreating MixinsUsing Multiple Mixinson Keyword in MixinsMixin vs InheritanceMixin vs InterfaceRecap - Animal System11Special Methods
toString() OverridehashCode & == OverrideComparable Interfacecall() MethodnoSuchMethod OverrideRecap - Custom Collection14Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern3Class Properties
Instance vs Static MembersFinal & Const FieldsLate VariablesStatic Methods & FieldsGetters and SettersRecap - Bank Account Manager6Inheritance
Basic InheritanceThe super KeywordMethod OverridingThe @override AnnotationThe final Class KeywordConstructors & InheritanceRecap - Employee Hierarchy9Polymorphism
Polymorphism BasicsPolymorphism via InterfacesRuntime Type CheckingThe is & as OperatorsCovariant KeywordRecap - Payment Processor