Abstract class in Typescript

Abstract classes in TypeScript provide a way to define classes that cannot be instantiated directly. They are used to create a base class with common functionality and structure, which other classes can extend and implement. Abstract classes can include both implemented methods and abstract methods. Abstract methods are methods that do not have an implementation and must be implemented by any subclass.

Here’s a detailed look at how abstract classes work in TypeScript:

Defining an Abstract Class

To define an abstract class, use the abstract keyword before the class keyword. Within an abstract class, you can define abstract methods using the abstract keyword. Abstract methods must be implemented by any derived classes.

Example of an Abstract Class


abstract class Animal {
  constructor(public name: string) {}

  // Abstract method (does not have an implementation)
  abstract makeSound(): void;

  // Normal method
  move(distance: number): void {
    console.log(`${this.name} moved ${distance} meters.`);
  }
}

class Dog extends Animal {
  constructor(name: string) {
    super(name);
  }

  // Implementing the abstract method
  makeSound(): void {
    console.log('Woof! Woof!');
  }
}

class Cat extends Animal {
  constructor(name: string) {
    super(name);
  }

  // Implementing the abstract method
  makeSound(): void {
    console.log('Meow!');
  }
}

const dog = new Dog('Tiger');
dog.makeSound();  // Output: Woof! Woof!
dog.move(10);  // Output: Tiger moved 10 meters.

const cat = new Cat('Miti');
cat.makeSound();  // Output: Meow!
cat.move(7);  // Output: Miti moved 7 meters.

In this example:

  • Animal is an abstract class with an abstract method makeSound and a regular method move.
  • Dog and Cat are concrete classes that extend Animal and implement the makeSound method.

Key Points

Cannot Instantiate Abstract Class: You cannot create an instance of an abstract class directly.


const animal = new Animal('Pet Animal');  // Error: Cannot create an instance of an abstract class.

Abstract Methods: Abstract methods do not have an implementation in the abstract class. Subclasses must provide an implementation for these methods.


abstract class Shape {
  abstract calculateArea(): number;
}

class Circle extends Shape {
  constructor(public radius: number) {
    super();
  }

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

const circle = new Circle(5);
console.log(circle.calculateArea());  // Output: 78.53981633974483

Regular Methods: Abstract classes can also contain methods with implementations, which can be inherited by subclasses.


abstract class Vehicle {
  constructor(public name: string) {}

  abstract startEngine(): void;

  stopEngine(): void {
    console.log(`${this.name} engine stopped.`);
  }
}

class Car extends Vehicle {
  constructor(name: string) {
    super(name);
  }

  startEngine(): void {
    console.log(`${this.name} engine started.`);
  }
}

const car = new Car('Tata');
car.startEngine();  // Output: Tata engine started.
car.stopEngine();  // Output: Tata engine stopped.

Protected Members: You can use protected members in abstract classes to allow access within derived classes while preventing access from outside the class hierarchy.


abstract class Machine {
  protected status: string = 'inactive';

  abstract activate(): void;

  getStatus(): string {
    return this.status;
  }
}

class Robot extends Machine {
  activate(): void {
    this.status = 'active';
    console.log('Robot activated.');
  }
}

const robot = new Robot();
robot.activate();  // Output: Robot activated.
console.log(robot.getStatus());  // Output: active

Conclusion

Abstract classes in TypeScript are powerful tools for creating a common base with shared functionality and structure that other classes can extend. They help enforce a contract for derived classes to implement specific methods while providing a mechanism to share common behavior.