You are currently viewing Abstract vs Interface vs Ordinary
Understand the distinctions between abstract classes, interfaces, and ordinary classes in TypeScript and gain insight into their use cases.

Abstract vs Interface vs Ordinary

Abstract vs Interface vs Ordinary

When working with TypeScript, there are three primary concepts that can be used to define custom types: abstract classes, interfaces, and ordinary classes. Each of these features has its purpose and use cases, so understanding their differences is essential for writing effective and maintainable code.

Abstract Classes

An abstract class serves as a blueprint for other classes and cannot be instantiated itself. It can contain both implemented and abstract methods, allowing derived classes to either inherit or implement them.

Here’s an example of an abstract class in TypeScript:

abstract class Vehicle {
  abstract start(): void;

  drive(): void {
    console.log('Driving...');
  }
}

In this example, the Vehicle class is marked as abstract, which means it cannot be directly instantiated. Derived classes can inherit from it and implement the start method while having access to the drive method.

Interfaces

An interface defines a contract that a class must adhere to. It specifies the properties, methods, and events that a class implementing the interface should have.

Consider the following interface definition:

interface Printable {
  print(): void;
}

Classes can implement one or multiple interfaces, declaring that they will provide an implementation for the methods defined in those interfaces. For example:

class Document implements Printable {
  print(): void {
    console.log('Printing document...');
  }
}

The Document class implements the Printable interface and is required to provide an implementation for the print method.

Ordinary Classes

Ordinary classes are the most common type of classes. They can be instantiated directly and serve as blueprints for creating objects.

Here’s an example of an ordinary class in TypeScript:

class Person {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  sayHello(): void {
    console.log(`Hello, my name is ${this.name}`);
  }
}

In this example, the Person class can be instantiated, and objects can be created based on its blueprint. It has a constructor and a method called sayHello.

Choosing the Right Feature

  • Use an abstract class when you want to provide a common base implementation for a group of related classes.
  • Use an interface when you want to define a contract that multiple classes should adhere to.
  • Use an ordinary class when you want to create objects based on a specific blueprint.

It’s important to understand the distinctions between abstract classes, interfaces, and ordinary classes in TypeScript to make informed design decisions and write clean and modular code.