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 methodmakeSound
and a regular methodmove
.Dog
andCat
are concrete classes that extendAnimal
and implement themakeSound
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.