An abstract class in TypeScript acts as a blueprint for related classes and cannot be instantiated directly.

- Can contain abstract methods or properties that subclasses must implement.
- Can contain concrete methods, properties, and constructors with shared functionality.
- Helps enforce a common structure while allowing subclasses to provide specific implementations.
abstract class Animal {
abstract makeSound(): void;
move(): void {
console.log('Moving...');
}
}
class Dog extends Animal {
makeSound(): void {
console.log('Bark');
}
}
const myDog = new Dog();
myDog.makeSound();
myDog.move();
Output:
Bark
Moving...
- Animal defines the abstract makeSound() method and concrete move() method.
- Dog extends Animal and implements makeSound().
- The Dog object can use both methods.
Features of Abstract Classes
- Cannot Be Instantiated: Abstract classes cannot be directly instantiated.
- Abstract Members: Abstract methods or properties must be implemented by subclasses.
- Concrete Members: Shared methods and properties can be defined with implementations.
- Constructors and Properties: Abstract classes can define constructors and properties for shared initialization.
- Polymorphism: Subclasses can be treated as instances of their abstract base class.
Applications of Abstract Classes
- Shared Functionality: Define common methods and properties for related classes.
- Enforcing Implementation: Require subclasses to implement specific members.
- Code Reuse: Avoid duplicating common functionality across subclasses.
- Encapsulation: Keep shared logic in a single base class.
More Example of Abstract Classes in TypeScript
Here are some examples:
Example 1: Abstract Class with Abstract Property
Abstract properties require subclasses to provide their own implementation.
abstract class Person {
abstract name: string;
display(): void {
console.log(this.name);
}
}
class Employee extends Person {
name: string;
empCode: number;
constructor(name: string, code: number) {
super();
this.name = name;
this.empCode = code;
}
}
const emp = new Employee('James', 100);
emp.display();
Output
James- Person declares the abstract name property and concrete display() method.
- Employee implements name and adds the empCode property.
- display() is inherited from Person.
Example 2: Abstract Class with Abstract Method
Abstract methods define behavior that each subclass must implement differently.
abstract class Shape {
abstract getArea(): number;
printArea(): void {
console.log(`The area is ${this.getArea()}.`);
}
}
class Circle extends Shape {
radius: number;
constructor(radius: number) {
super();
this.radius = radius;
}
getArea(): number {
return Math.PI * this.radius * this.radius;
}
}
const circle = new Circle(5);
circle.printArea();
Output:
The area is 78.53981633974483.- Shape declares the abstract getArea() method.
- Circle implements getArea() for calculating a circle's area.
- printArea() provides shared functionality through the abstract base class.
Best Practices
- Use abstract classes when related classes share common functionality.
- Use abstract members when subclasses must provide their own implementation.
- Keep shared logic in concrete methods of the abstract class.
- Instantiate concrete subclasses rather than the abstract class itself.