What's the difference between 'extends' and 'implements'

The sixty-four-dollar question: what’s the difference between implementing a and extending a class? Let’s make things clear in no time.

In This Article:

Extending a class

Let’s say we have a class that represents a random movie. Every movie needs to be played or paused. So our class will look like this:

class Movie {
  play() {
    console.log(`We are watching a random Movie`);
  }
  pause() {
    console.log(`Pausing the movie..`);
  }
}

Now suppose we want to write a class that represents a particular genre of movie, let’s say a western movie. We should rewrite our play() and pause() methods but we know that (almost) always repeating code is bad. So?

So we will write a class that extends Movie and inherits all its methods.

We can add new methods and properties specific to this class, such as the number of shots fired in the movie. Or we can override existing methods. Try this code in your browser console:

class Movie {
  constructor(data) {
    this.title = data.title;
    this.director = data.director;
  }
  play() {
    console.log(`We are watching a random Movie`);
  }
  pause() {
    console.log(`Pausing the movie..`);
  }
}

class Western extends Movie {
  constructor(data) {
    super(data)
    this.shotsFired = 110;
  }
  play() {
    console.log(`We are watching ${this.title} by ${this.director}!`);
    console.log(`${this.shotsFired} shots fired so far`);
  }
}

const rioBravo = new Western({
  title: 'Rio Bravo',
  director: 'John Ford'
});

rioBravo.play(); // We are watching a Rio Bravo by John Ford! 110 shots fired so far

rioBravo.pause(); // Pausing the movie..

This way we can have infinite genres: comedy, romance, noir… without ever repeating our code.

Implementing a class

The goal here is not to write less code, but to write better code.

An interface in fact only serves to establish a contract with the developer who will be forced to implement his class in that way. This will avoid many errors and side effects.

As you can see in the code below, the Movie interface will force the developer to write a class that contains a title and a director as strings, play() and pause() methods, and an optional year (it’s optional because we have this syntax with the question mark year?:). If implemented, year must be a number.

interface Movie {
    title: string;
    director: string;
    year?: number;
    play(): void;
    pause(): void;
}

class Western implements Movie {
    title: string;
    director: string;

    constructor(data: MovieData) {
        this.title = data.title;
        this.director = data.director;
    }

    play(): void {
        console.log(`We are watching ${this.title} by ${this.director}!`);
    }

    pause(): void {
        console.log(`Pausing the movie..`);
    }
}

const rioBravo = new Western({
    title: 'Rio Bravo',
    director: 'John Ford',
    year: 1950
});

If even one rule of the contract is broken, the compiler will return an error.

Of course also MovieData will be an interface

Wrapping up

To recap, the key differences between the two keywords are.

Extends Implements
Both JavaScript and TypeScript Only TypeScript
The new class is a child The new class is the implementation of the interface
The new class inherits all properties and methods of the parent and can add new ones. The class must implement its own methods
The new class has no constraints The class is forced to adhere to the contract established with the interface
Each class can be extended and still can be used as a normal class The interface is not concrete class, it can’t be used as is
Useful for code reusability Useful for type safety and code maintainability
Multiple inheritance is not supported Multiple interface is supported

Explained with just one image

clint-eastwood.png

Irene Iaccio

Freelance web developer

Subscribe to the monthly digest!

I'll use your email only to send you the latest posts once a month.