In TypeScript, abstract classes are a powerful feature that allow you to define a base class with some methods that must be implemented by any derived (child) classes. They cannot be instantiated directly and serve as blueprints for other classes. Abstract classes are particularly useful in scenarios where you want to enforce a certain structure or behavior across multiple related classes.
An abstract class is declared using the abstract keyword before the class keyword. It can contain both abstract methods (which do not have an implementation and must be implemented by derived classes) and concrete methods (which have an implementation).
public, private, protected) to control the visibility of their members.Let's dive into some practical examples to understand how abstract classes work in TypeScript.
abstract class Animal {
constructor(public name: string) {}
// Abstract method
abstract makeSound(): void;
// Concrete method
move(distanceInMeters: number): void {
console.log(`\${this.name} moved \${distanceInMeters}m.`);
}
}
In this example, `Animal` is an abstract class with one abstract method `makeSound()` and one concrete method `move()`. The constructor initializes the `name` property.
### Example 2: Derived Class
To use the abstract class, you need to create a derived class that implements all the abstract methods:
```typescript
class Dog extends Animal {
makeSound(): void {
console.log(`\${this.name} barks.`);
}
}
const myDog = new Dog("Buddy");
myDog.makeSound(); // Output: Buddy barks.
myDog.move(10); // Output: Buddy moved 10m.
In this example, Dog is a derived class that implements the makeSound() method. You can now create instances of Dog, but not directly from Animal.
Abstract methods can also have parameters:
abstract class Vehicle {
constructor(public brand: string) {}
abstract startEngine(fuelType: string): void;
stopEngine(): void {
console.log(`\${this.brand} engine stopped.`);
}
}
class Car extends Vehicle {
startEngine(fuelType: string): void {
console.log(`\${this.brand} car started with \${fuelType}.`);
}
}
const myCar = new Car("Toyota");
myCar.startEngine("petrol"); // Output: Toyota car started with petrol.
myCar.stopEngine(); // Output: Toyota engine stopped.
In this example, Vehicle is an abstract class with an abstract method startEngine() that takes a parameter. The Car class implements this method.
Abstract classes can also have properties:
abstract class Shape {
protected color: string;
constructor(color: string) {
this.color = color;
}
abstract area(): number;
describe(): void {
console.log(`This shape is \${this.color} and has an area of \${this.area()} square units.`);
}
}
class Circle extends Shape {
private radius: number;
constructor(radius: number, color: string) {
super(color);
this.radius = radius;
}
area(): number {
return Math.PI * this.radius * this.radius;
}
}
const myCircle = new Circle(5, "red");
myCircle.describe(); // Output: This shape is red and has an area of 78.53981633974483 square units.
In this example, Shape is an abstract class with a protected property color. The Circle class extends Shape and implements the area() method.
After mastering abstract classes, you might want to explore Generics in TypeScript. Generics provide a way to create reusable components that can work with a variety of types while providing type safety. This will further enhance your ability to write flexible and maintainable code.
Stay tuned for more advanced topics in our TypeScript curriculum!