66

I wrote a couple of lines of code to experiment and differentiate between these two: interface and abstract class.

I found out that they have the same restriction.

interface IPerson {
  name: string;
  talk(): void;
}

interface IVIP {
  code: number;
}

abstract class Person {
  abstract name: string;
  abstract talk(): void;
}

class ManagerType1 extends Person {
  // The error I get is that I need to implement the talk() method
  // and name property from its base class.
}

class ManagerType2 implements IPerson {
  // The error I get is that I need to implement the talk() method 
  // and the name property from the interface.
}


class ManagerType3 implements IPerson, IVIP {
  // Now the error I get is that I need to implement all the 
  // properties and methods of the implemented interfaces to the derived class
}

As what I found is, there are no clear differences between these two since they both implement the same restriction. The only thing I notice is inheritance and implementation.

  1. A class can only extend to a single base class
  2. A class can implement multiple interfaces.

Did I catch it right? If so when do I need to use one?

UPDATE

I do not know if this is the right answer but you can really use BOTH depending on your situation. OOP is really cool.

class ManagerType3 extends Person implements IPerson, IVIP {
  // Now the restriction is that you need to implement all the abstract
  // properties and methods in the base class and all 
  // the properties and methods from the interfaces
}
Istiyak Tailor
  • 1,570
  • 3
  • 14
  • 29
Shift 'n Tab
  • 8,808
  • 12
  • 73
  • 117
  • 1
    In addition to restrictions base class can provide implementation/partial implementation, and the interface only defines shape/contract – Aleksey L. May 01 '18 at 07:34
  • @AlekseyL. yes thanks a lot, i figure out that interface was meant for a standard, same as abstract class however you can add some method that is persistent to every derived class. – Shift 'n Tab May 01 '18 at 08:08
  • Possible duplicate of [Difference between interfaces and classes in Typescript](https://stackoverflow.com/questions/40973074/difference-between-interfaces-and-classes-in-typescript) – Michael Freidgeim Oct 04 '19 at 13:34

3 Answers3

89

Interfaces

An interface is a contract that defines the properties and what the object that implements it can do. For example, you could define what can do a Plumber and an Electrician:

interface Electrician {
  layWires(): void
}

interface Plumber {
  layPipes(): void
}

Then, you can consume the services of your interfaces:

function restoreHouse(e: Electrician, p: Plumber) {
  e.layWires()
  p.layPipes()
}

Notice that the way you have to implement an interface is free. You can do that by instantiating a class, or with a simple object:

let iAmAnElectrician = {
  layWires: () => { console.log("Work with wires…") }
}

An interface doesn't exist at all at runtime, so it is not possible to make an introspection. It is the classic JavaScript way to deal with object programming, but with a good control at compile time of the defined contracts.

Abstract classes

A class is both a contract and the implementation of a factory. An abstract class is also an implementation but incomplete. Especially, an abstract class exists at runtime, even if it has only abstract methods (then instanceof can be used).

When you define an abstract class, you often try to control how a process has to be implemented. For example, you could write something like this:

abstract class HouseRestorer {
  protected abstract layWires(): void
  protected abstract layPipes(): void
  restoreHouse() {
    this.layWires()
    this.layPipes()
  }
}

This abstract class HouseRestorer defines how the methods layWires and layPipes will be used, but it is up to a child class to implement the specialized treatments before it can be used.

Abstract classes are a traditional OOP approach, which is not traditional in JavaScript.

Both approaches allow the same things to be done. They are two different ways of solving a problem.

Paleo
  • 21,831
  • 4
  • 65
  • 76
52

A bigger difference in TypeScript is that (abstract) classes are available at runtime, while interfaces are compile time only. This means that you cannot, for example, use instanceof with interfaces.

let x: any;

if (x instanceof IPerson) { // Error: 'IPerson' only refers to a type, but is being used as a value here.

}

if (x instanceof Person) { // OK

}

If you don't really need runtime types, like the above example, or want to have implementations in the concrete classes only, go for interfaces. As they are compile time only, the size of the generated JS will be smaller.

Wickoo
  • 6,745
  • 5
  • 32
  • 45
7

Abstract Class

  • Can't be used to create an object directly, because it does not have complete implementation

  • Only used as a parent class

  • An abstract class can implement one or more interface.

    interface Name {
       firstName: string
       lastName: string;
    }
    
    interface Work {
        doWork(): void;
    }
    
    abstract class BaseEmployee implements Name, Work {
      firstName: string;
      lastName: string;
    
      constructor(firstName: string, lastName: string) {
          this.firstName = firstName;
          this.lastName = lastName;
      }
    
      abstract doWork(): void;
    

    }

  • can contain real implementaion for some methods

  • the implemented methods can refer to other methods that do not actually exist yet( you still have to provide names and types for the unimplemented methods)

  • Abstract class compile to JavaScript functions.

Interface

  • Unlike abstract classes, interfaces don’t implement methods or define a constructor and just define a shape. Interfaces are implemented by classes through the implements keyword

    class Student implements PersonInterface{}
    
  • Interfaces can be extended, just like classes. Abstract class are only parent

    interface Person {
          name: string;
          getDetails(): string;
       }
       interface CatOwner extends Person {
          catName: string;
          getCatDetails(): string;
       }
    
  • There is no JavaScript equivalent to interfaces, and no details of interfaces are included in the JavaScript code generated by the TypeScript compiler. This means that the instanceof keyword cannot be used to narrow interface types.

Yilmaz
  • 35,338
  • 10
  • 157
  • 202