Interfaces and Abstract Classes in TypeScript

When working with TypeScript, it is essential to leverage the power of interfaces and abstract classes to ensure code reusability, maintainability, and strong typing. These concepts enable developers to define contracts and provide a blueprint for creating objects.

Interfaces

Interfaces in TypeScript provide a way to define the structure of objects. They act as a contract that enforces certain properties, methods, or behaviors that a class implementing the interface must adhere to. Essentially, an interface describes the shape of an object.

To define an interface, you use the interface keyword followed by the name of the interface and curly braces containing the properties and methods that need to be implemented. For example:

interface Shape {
  color: string;
  area(): number;
}

In this example, we have created an interface called Shape that requires any object implementing it to have a color property of type string and an area method that returns a number.

To implement an interface, a class must use the implements keyword followed by the name of the interface. The class then needs to provide implementations for all the properties and methods defined in the interface.

class Circle implements Shape {
  color: string;
  radius: number;

  constructor(color: string, radius: number) {
    this.color = color;
    this.radius = radius;
  }

  area(): number {
    return Math.PI * this.radius * this.radius;
  }
}

In the above example, the Circle class implements the Shape interface by providing a color property and an area method. The class can also have additional properties like radius specific to itself.

Interfaces are incredibly useful when you need to enforce a specific structure across multiple classes or when you want to create reusable code components.

Abstract Classes

Abstract classes, on the other hand, are similar to interfaces but can provide default implementations for certain methods. Unlike interfaces, abstract classes can contain implementation details and state.

To define an abstract class, you use the abstract keyword followed by the name of the class. Similar to regular classes, abstract classes can have properties, methods, and constructors. However, you cannot create instances of an abstract class directly.

abstract class Vehicle {
  protected brand: string;

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

  abstract accelerate(): void;

  stop(): void {
    console.log('Vehicle stopped.');
  }
}

In the above example, we have an abstract class called Vehicle with a constructor and two methods: accelerate and stop. The accelerate method is marked as abstract, which means that any class extending this abstract class must provide its implementation.

To extend an abstract class, a class uses the extends keyword followed by the name of the abstract class. The extending class must implement any abstract methods defined in the abstract class.

class Car extends Vehicle {
  accelerate(): void {
    console.log('Car accelerating...');
  }
}

In this example, the Car class extends the Vehicle abstract class and implements the accelerate method. It also inherits the stop method implementation from the abstract class.

Abstract classes are beneficial when you want to define a base class with shared behavior and enforce derived classes to provide certain implementations.

Conclusion

Interfaces and abstract classes are powerful features in TypeScript that enable developers to create more robust and maintainable code. Interfaces define contracts that ensure consistency across objects, while abstract classes provide a blueprint for derived classes to follow. By using these concepts effectively, developers can enhance code reusability and enforce strong typing, resulting in more reliable and scalable applications.


noob to master © copyleft