flutter
/

Dart Interfaces – Implicit Interfaces and the `implements` Keyword

Last Sync: Today

On this page

10
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

flutter

Dart Interfaces – Implicit Interfaces and the `implements` Keyword

What is an Interface?

An interface defines a contract that a class must adhere to. It specifies a set of methods and properties that the class must implement, but it does not provide any implementation itself. In many languages (like Java), you declare an interface explicitly. In Dart, however, every class implicitly defines an interface containing all its instance members (methods, getters, setters). This means you can use any class as an interface.

The implements Keyword

To make a class adhere to an interface (i.e., to implement the contract of another class), use the implements keyword. The implementing class must provide concrete implementations for all members (methods, getters, setters) of the interface class.

DARTRead-only
1
// This class acts as an interface
class Flyable {
  void fly() {}
  int get altitude;
}

// Bird implements the Flyable interface
class Bird implements Flyable {
  @override
  void fly() {
    print('Bird is flying');
  }

  @override
  int get altitude => 1000;
}

void main() {
  Bird bird = Bird();
  bird.fly();
  print('Altitude: ${bird.altitude}');
}

Notice that even though Flyable is a class with empty method bodies, when another class implements it, it must provide its own versions of fly() and the getter altitude. The original implementation (if any) is not inherited – only the signature matters.

Implementing Multiple Interfaces

One of the key benefits of interfaces is that a class can implement multiple interfaces, enabling it to fulfill multiple contracts. This is different from inheritance, where a class can only extend one superclass.

DARTRead-only
1
class Swimmable {
  void swim() {}
}

class Walkable {
  void walk() {}
}

class Duck implements Swimmable, Walkable {
  @override
  void swim() {
    print('Duck swims');
  }

  @override
  void walk() {
    print('Duck walks');
  }
}

void main() {
  Duck duck = Duck();
  duck.swim();
  duck.walk();
}

Abstract Classes as Interfaces

You can also use abstract classes to define interfaces. Abstract classes can contain both abstract methods (without implementation) and concrete methods. When another class implements an abstract class, it must implement all members (both abstract and concrete).

DARTRead-only
1
abstract class Drawable {
  void draw(); // abstract
  void info() {
    print('This is a drawable object');
  }
}

class Circle implements Drawable {
  @override
  void draw() {
    print('Drawing a circle');
  }

  @override
  void info() {
    print('Circle info'); // Must implement even though it had a body
  }
}

Difference Between extends and implements

    • extends creates a subclass that inherits the implementation of the superclass. You can override methods but you don't have to implement every method (you get them for free).
    • implements makes the class adhere to an interface – it must provide its own implementation for all members of the implemented class. No code is inherited.
    • A class can extend only one class, but can implements multiple interfaces.

Using @override with Interfaces

When you implement a method from an interface, it's good practice (though optional) to use the @override annotation. This helps the compiler ensure you're actually overriding a member, and it improves code readability.

Interface vs Abstract Class vs Mixin

It's important to understand the differences between these three code reuse mechanisms:

    • Interface (via implements): No implementation inheritance, only contract. Can implement multiple.
    • Abstract class (via extends): Can have both abstract and concrete methods, fields, constructors. Can only extend one.
    • Mixin (via with): Provides implementation but is not meant to be instantiated; can be mixed into multiple classes.

Best Practices

    • Use interfaces to define capabilities that can be implemented by unrelated classes.
    • Name interfaces according to the ability they represent (e.g., Flyable, Comparable, Iterable).
    • Keep interfaces small and focused (Interface Segregation Principle).
    • Prefer abstract class over a concrete class as an interface if you want to provide some base implementation (but be aware it will still require full implementation when used with implements).
    • When a class implements multiple interfaces, ensure there are no conflicting method signatures; if there are, you must provide a single implementation that satisfies all.

Complete Example

DARTRead-only
1
// Define several interfaces (as classes)
class Printable {
  void printData() {}
}

class Storable {
  void save() {}
  void load() {}
}

class Serializable {
  String toJson() => '';
}

// A class that implements multiple interfaces
class Document implements Printable, Storable, Serializable {
  String content;

  Document(this.content);

  @override
  void printData() {
    print('Printing document: $content');
  }

  @override
  void save() {
    print('Saving document...');
  }

  @override
  void load() {
    print('Loading document...');
  }

  @override
  String toJson() {
    return '{"content": "$content"}';
  }
}

void main() {
  Document doc = Document('Hello, Dart!');
  doc.printData();
  doc.save();
  print('JSON: ${doc.toJson()}');
}

Key Takeaways

    • In Dart, every class defines an implicit interface.
    • Use implements to make a class adhere to one or more interfaces.
    • When implementing an interface, you must provide implementations for all members of that interface.
    • A class can implement multiple interfaces but extend only one superclass.
    • Interfaces are ideal for defining contracts that multiple unrelated classes can fulfill.

Try it yourself

class Greetable {
  void greet() {}
}

class Person implements Greetable {
  String name;
  Person(this.name);

  @override
  void greet() {
    print('Hello, my name is $name');
  }
}

void main() {
  Person p = Person('Alice');
  p.greet();
}

Test Your Knowledge

Q1
of 4

How do you make a class implement an interface in Dart?

A
extends
B
implements
C
with
D
interface
Q2
of 4

How many interfaces can a Dart class implement?

A
0
B
1
C
2
D
Any number
Q3
of 4

When a class implements an interface, what must it do?

A
Inherit the implementation
B
Provide its own implementation for all members of the interface
C
Only implement abstract methods
D
Use the `@override` annotation for every method
Q4
of 4

True or False: In Dart, you must use the `interface` keyword to define an interface.

A
True
B
False

Frequently Asked Questions

Does Dart have an `interface` keyword?

No, Dart does not have a separate interface keyword. Instead, every class implicitly defines an interface. You use the implements keyword to make a class implement that interface.

Can a class implement an interface without providing all methods?

No, the implementing class must provide concrete implementations for every member of the interface. If it fails to do so, you'll get a compile‑time error. The class can be declared abstract if you want to leave some methods unimplemented.

What happens if two interfaces have a method with the same name?

The class must provide a single implementation that satisfies both interfaces. Dart's type system will ensure that the implementation matches the signatures of both. If the signatures are incompatible (different parameter types), you'll get a compile error.

Can I implement a class that already has implementation?

Yes, you can. The implementation in the original class is ignored when used as an interface; the implementing class must provide its own implementation.

When should I use `implements` vs `extends`?

Use extends when you want to inherit behavior and possibly override parts of it. Use implements when you only want to enforce a contract and you're providing all the implementation yourself. Often you'll combine both: extends one class and implements several interfaces.

Can I use a mixin as an interface?

Yes, a mixin can also be used as an interface with implements. But that would require the implementing class to provide all the mixin's methods, losing the code reuse that mixins offer. It's better to use with for mixins.

Previous

dart mixins

Next

dart abstract classes

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.