skip to content

In Dart, what is the difference between extends and implements, and what must a class that implements another class re-declare?

level: juniorimportance: must knowfreq 74%

answer

  1. every class is an interface
  2. one superclass, many interfaces
  3. implements inherits no code
  4. fields count as getters and setters
  5. constructors and statics are not in it

basics

~20 s

extends makes a subclass that inherits the superclass's implementation, and a class has exactly one superclass. implements only adopts the implicit interface of each listed class, so the class must itself implement every instance member, fields included, but not constructors or statics.

solid answer

~40 s

Every Dart class implicitly defines an interface: all its instance members, including the getters and setters that its fields induce. `extends` gives you that interface **and** the implementation — you inherit method bodies and fields, override what you need and call `super`. Dart allows only one superclass. `implements` gives you the type only: the class becomes a subtype of each listed class but inherits no code, so it must provide every instance member itself — including `width` and `height` if the other class declares them as fields. Constructors and static members are not part of an interface. You may implement several classes at once, and the same class cannot appear in both `extends` and `implements`. Private members of a class from another library cannot be implemented by you at all.

go deeper

for a junior

Recall that extends inherits code from one superclass while implements adopts any number of implicit interfaces and inherits nothing.

for a middle

Explain what the implicit interface contains, why fields must be re-declared as fields or getters, and why constructors and statics are excluded.

for a senior

Judge the coupling: implementing a concrete class you do not own breaks whenever it grows, and private members across libraries fail at runtime.

for a principal

Decide which types in a shared codebase are published as contracts to implement and which are meant only to be extended or used.

## Every class is an interface Dart has no separate interface declaration of the kind some languages use. Instead, **every class implicitly defines an interface** containing all of its **instance members**: methods, operators, getters and setters — and, because every field induces a getter (plus a setter unless it is `final`), its fields too. Constructors and `static` members are not part of that interface. That gives a class two ways to relate to another class. ## `extends`: type plus implementation ```dart abstract class Shape { double get area; String describe() => '$name: ${area.toStringAsFixed(2)} m2'; String get name; } class Rect extends Shape { Rect(this.width, this.height); final double width, height; @override String get name => 'rect'; @override double get area => width * height; } ``` `Rect` inherits `describe()` without restating it. Key properties of `extends`: - **Single inheritance**: a class has exactly one superclass (implicitly `Object` if none is named). - Inherited members come with their **implementations**; the subclass overrides selectively. - The subclass must call a **generative superclass constructor**, explicitly or implicitly. - `super.member` reaches the superclass implementation. ## `implements`: type only ```dart class TracedOutline implements Rect { TracedOutline(this.width, this.height); @override final double width, height; @override String get name => 'traced'; @override double get area => width * height * 0.98; @override String describe() => 'traced outline, ${area.toStringAsFixed(1)} m2'; } ``` `TracedOutline` is usable anywhere a `Rect` is expected, but it inherits **nothing**: it had to re-declare `width`, `height`, `name`, `area` **and** `describe()`, including the member `Rect` itself inherited from `Shape`. Key properties: 1. A class may implement **many** interfaces: `class Tile implements Rect, Comparable<Tile>`. 2. Every instance member of every listed interface must be implemented, or the analyzer reports missing concrete implementations — unless the class is `abstract`, or overrides `noSuchMethod` so the compiler fills the gaps with forwarders. 3. **No constructors** are involved; the implementing class writes its own. 4. The same type cannot appear in both `extends` and `implements` (`implements_super_class`), nor twice in `implements` (`implements_repeated`). ## What the difference costs | | `extends Rect` | `implements Rect` | |---|---|---| | Subtype of `Rect` | yes | yes | | Inherits method bodies | yes | no | | Inherits field storage | yes | no — re-declare as fields or getters | | How many allowed | one | any number | | Runs `Rect`'s constructor | yes | no | | `super.area` available | yes | no | | New member added to `Rect` later | inherited automatically | implementers break until they add it | The last row is the practical one: implementing a class ties you to its **whole** interface, so every new member its author adds is a compile error in your code. ## Private members across libraries A class's interface also contains its **private** members, but only code in the same library can name them. If you implement a class from another library that has private members, you cannot provide them. Should that library call one of them on your object, the call fails at runtime with a `NoSuchMethodError`. Preventing that situation is one purpose of Dart 3's class modifiers. ## When to use which - Use `extends` when the subclass **is a specialised version** and should reuse behaviour: `Square extends Rect`. - Use `implements` when you need **substitutability without the implementation** — a test fake, an adapter over another data source, or conforming to several unrelated contracts such as `Comparable`. - Prefer implementing **abstract** classes designed as contracts; implementing a concrete class couples you to details its author may change.

  • In Dart, can a class both extend one class and implement others?
    Yes: `class Square extends Rect implements Comparable<Square>` is valid. It inherits `Rect`'s implementation, and must itself implement `compareTo` for `Comparable`. The one restriction is that the superclass cannot also be listed in `implements`, and no type may be listed twice there.
  • In Dart, what happens to a class that implements a concrete class when that class gains a new public method?
    It stops compiling. Implementing adopts the entire interface without any implementation, so the new member is missing from the implementer until someone adds it. A subclass that extends the class would simply inherit the new method. That is why implementing a class you do not own is a stronger coupling than it looks.

saying these in an interview costs you the question

  • A class that implements another inherits its method bodies
  • Fields are not part of Dart's implicit interface, only methods
  • Dart supports multiple inheritance with extends A, B
  • An implementing class must also re-declare the other class's constructors
  • You need a separate interface declaration before a class can be implemented