Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I would like to know what Man and Child have in common and how they differ.

class Person {
  name: string;
  age: number;
}
class Child extends Person {}
class Man implements Person {}
like image 240
davejoem Avatar asked Oct 17 '22 17:10

davejoem


People also ask

What is the difference between extends and implements?

Difference: implements means you are using the elements of a Java Interface in your class. extends means that you are creating a subclass of the base class you are extending. You can only extend one class in your child class, but you can implement as many interfaces as you would like.

What is the use of implements in typescript?

In Typescript an implements clause can be used to verify that a class conforms to a specific interface. If a class fails to implement an interface correctly, an error will be generated. Classes can implement a single interface or multiple interfaces at once.

What is extend in typescript?

The extends keyword removes the need of having to repeat the members of other types at multiple places and shows the relation between the interfaces to the reader of the code. You can extend from multiple interfaces by separating them with a comma.

Can we use extends and implements together in typescript?

Yes you can do that.


2 Answers

Short version

  • extends means:

The new class is a child. It gets benefits coming with inheritance. It has all the properties and methods of its parent. It can override some of these and implement new ones, but the parent stuff is already included.

  • implements means:

The new class can be treated as the same "shape", but it is not a child. It could be passed to any method where Person is required, regardless of having a different parent than Person.

More ...

In OOP (languages like C# or Java) we would use

extends to profit from inheritance.

... Inheritance in most class-based object-oriented languages is a mechanism in which one object acquires all the properties and behaviours of the parent object. Inheritance allows programmers to: create classes that are built upon existing classes ...

implements will be more for polymorphism.

... polymorphism is the provision of a single interface to entities of different types...

So we can have a completely different inheritance tree for our class Man:

class Man extends Human ...

but if we also declare that Man can pretend to be the Person type:

class Man extends Human 
          implements Person ...

...then we can use it anywhere Person is required. We just have to fulfil Person's "interface" (i.e. implement all its public stuff).

implement other class? That is really cool stuff

Javascript's nice face (one of the benefits) is built-in support for duck typing.

"If it walks like a duck and it quacks like a duck, then it must be a duck."

So, in Javascript, if two different objects have one similar method (e.g. render()) they can be passed to a function which expects it:

function(engine){
  engine.render() // any type implementing render() can be passed
}

To not lose that in Typescript, we can do the same with more typed support. And that is where

class implements class

has its role, where it makes sense.

In OOP languages as C#, no way to do that.

The documentation should help here:

Interfaces Extending Classes

When an interface type extends a class type it inherits the members of the class but not their implementations. It is as if the interface had declared all of the members of the class without providing an implementation. Interfaces inherit even the private and protected members of a base class. This means that when you create an interface that extends a class with private or protected members, that interface type can only be implemented by that class or a subclass of it.

This is useful when you have a large inheritance hierarchy, but want to specify that your code works with only subclasses that have certain properties. The subclasses don’t have to be related besides inheriting from the base class. For example:

class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Button extends Control implements SelectableControl {
    select() { }
}

class TextBox extends Control {
    select() { }
}

// Error: Property 'state' is missing in type 'Image'.
class Image implements SelectableControl {
    private state: any;
    select() { }
}

class Location {

}

So, while

  • extends means it gets all from its parent
  • implements in this case it's almost like implementing an interface. A child object can pretend that it is its parent... but it does not get any implementation.
like image 124
Radim Köhler Avatar answered Oct 28 '22 14:10

Radim Köhler


You have classes and interfaces in typescript (and some other OO languages).

An interface has no implementation; it's just a "contract" of what members/method this type has.
For example:

interface Point {
    x: number;
    y: number;
    distance(other: Point): number;
}

Instances that implement this Point interface must have two members of type number: x and y', and one method, distance, which receives another Pointinstance and returns anumber`.
The interface doesn't implement any of those.

Classes are the implementations:

class PointImplementation implements Point {
    public x: number;
    public y: number;
    
    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }
    
    public distance(other: Point): number {
        return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));
    }
}

(code in playground)

In your example, you treat your Person class once as a class when you extend it and once as an interface when you implement it.
Your code:

class Person {
    name: string;
    age: number;
}
class Child  extends Person {}

class Man implements Person {}

It has a compilation error saying:

Class 'Man' incorrectly implements interface 'Person'. Property' name' is missing in type 'Man'.

And that's because interfaces lack implementation.
So if you implement a class, then you only take its "contract" without the implementation, so you'll need to do this:

class NoErrorMan implements Person {
    name: string;
    age: number;
}

(code in playground)

The bottom line is that you want to extend another class in most cases and not to implement it.

like image 38
Nitzan Tomer Avatar answered Oct 28 '22 15:10

Nitzan Tomer