Interfaces in Dart
Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 45 of 110.
Unlike many languages that have a dedicated interface keyword, Dart takes a different approach. In Dart, every class automatically defines an interface. This interface consists of all the public members (methods and properties) that the class declares.
When you want a class to promise it will provide certain functionality without inheriting implementation, you use the implements keyword:
class Printer {
void printDocument(String content) {
print('Printing: $content');
}
}
class Scanner {
void scan() {
print('Scanning document');
}
}
// MultiFunctionDevice must implement ALL methods from both classes
class MultiFunctionDevice implements Printer, Scanner {
@override
void printDocument(String content) {
print('MFD printing: $content');
}
@override
void scan() {
print('MFD scanning');
}
}The key difference from extends is that implements doesn't inherit any code. You must provide your own implementation for every method and property defined in the interface. This is a contract - you're promising your class will have these capabilities, but you decide exactly how they work.
This approach gives Dart flexibility. You can use abstract classes when you want to define interfaces with no implementation, or use regular classes as interfaces when it makes sense. The next lesson explores how this "implicit interface" concept works in more detail.
Challenge
EasyLet's build a media player system that demonstrates how the implements keyword works in Dart. You'll create classes that serve as interfaces and then implement them in a single device that combines multiple capabilities.
You'll organize your code into two files:
media.dart: Define your interface classes and the implementing class here:- An
AudioPlayerclass with a methodplayAudio(String track)that printsPlaying audio: [track] - A
VideoPlayerclass with a methodplayVideo(String title)that printsPlaying video: [title] - A
SmartTVclass that implements bothAudioPlayerandVideoPlayer. Sinceimplementsdoesn't inherit any code, you must provide your own implementations for both methods. YourSmartTVshould printSmartTV audio: [track]for audio andSmartTV video: [title]for video
- An
main.dart: Import your media file and demonstrate how a single class can implement multiple interfaces:- Create a
SmartTVinstance - Call
playAudio('Jazz Collection') - Call
playVideo('Nature Documentary')
- Create a
Notice how SmartTV must provide its own implementation for every method from both interfaces - it doesn't inherit the original implementations from AudioPlayer or VideoPlayer. This is the key difference between implements and extends.
Expected output:
SmartTV audio: Jazz Collection
SmartTV video: Nature DocumentaryCheat sheet
In Dart, every class automatically defines an interface consisting of all its public members. To implement an interface without inheriting code, use the implements keyword:
class Printer {
void printDocument(String content) {
print('Printing: $content');
}
}
class Scanner {
void scan() {
print('Scanning document');
}
}
// Must implement ALL methods from both classes
class MultiFunctionDevice implements Printer, Scanner {
@override
void printDocument(String content) {
print('MFD printing: $content');
}
@override
void scan() {
print('MFD scanning');
}
}Key differences from extends:
implementsdoesn't inherit any code implementation- You must provide your own implementation for every method and property
- A class can implement multiple interfaces
- It's a contract promising your class will have these capabilities
Try it yourself
import 'media.dart';
void main() {
// TODO: Create a SmartTV instance
// TODO: Call playAudio('Jazz Collection')
// TODO: Call playVideo('Nature Documentary')
}
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