ComparisonComparisons

extends vs implements

extends inherits fields and code from a base class, while implements only forces a class to have an interface’s methods and fields, without any of its code.

On this page

Side-by-side comparison

#

Example

#
TypeScript
class Person {
  constructor(public name: string) {}

  greet(): string {
    return `Hi, I am ${this.name}`
  }
}

interface Scorable {
  score(): number
}

class Student extends Person implements Scorable {
  constructor(name: string, private points: number) {
    super(name)
  }

  score(): number {
    return this.points
  }
}

const student = new Student('Emma', 92)
console.log(student.greet())
console.log(student.score())
Result
Hi, I am Emma
92

Definition and usage

#

You use both keywords in a class declaration to connect it to another type, and the compiler checks both: if the class doesn’t meet the requirements, it reports an error. A class can extend only one base class, but implement several interfaces at once.

The difference is in what the class gets. extends between classes inherits real code: the fields, methods, and constructor of the base class, which you can call through super() or override. implements inherits no code at all, it only checks at compile time that the class itself has implemented everything the interface promises. extends also works between interfaces, where it extends the list of required fields.

When classes are meant to share common logic, e.g. a shared constructor or a helper method, use extends. When you only want to guarantee that different, unrelated classes have certain methods, e.g. Comparable or Serializable, use implements. Interfaces that describe capabilities combine better than deep class inheritance.

Syntax

#
Syntax
class Derived extends Base { … }
class SomeClass implements SomeInterface { … }

More examples

#
extends inherits code, implements doesn’t
TypeScript
class Shape {
  describe(): string {
    return 'A shape'
  }
}

class Circle extends Shape {}

const circle = new Circle()
console.log(circle.describe())
console.log(circle instanceof Shape)
Result
A shape
true
implements forces its own implementation
TypeScript
interface Scorable {
  score(): number
}

class Exam implements Scorable {}
// Error: Class 'Exam' incorrectly implements interface 'Scorable'.
//   Property 'score' is missing in type 'Exam' but required in type 'Scorable'.

Good practices

#
  • One class can implement several interfaces, but extend only one class. If you need several independent “abilities,” reach for interfaces.
  • implements only checks types. You still have to type the method parameters in the class itself, the compiler doesn’t take them over from the interface.
  • Deep extends chains are hard to maintain. Composition is often better: a class takes another object as a dependency instead of inheriting from it.

Related entries

#

Spotted a mistake or missing an example? Write to us.