Abstract Classes
Define a partial base class that guarantees shared behaviour but cannot be instantiated directly.
An abstract class is a base you can inherit from but never new directly. It can mix concrete, ready-to-use members with abstract ones that subclasses are obliged to implement.
abstract class Shape {
abstract area(): number; // subclass must provide
describe(): string { // shared, already implemented
return `Area is ${this.area().toFixed(2)}`;
}
}
// new Shape() // Error: cannot instantiate an abstract classThis is the tool for the "template method" pattern: the base fixes the overall algorithm and delegates the variable step to subclasses. You share real code and enforce a contract at once β something a plain interface cannot do because interfaces carry no implementation.
Example
When to use it
- A DataExporter abstract class provides a shared export() method while forcing subclasses to implement serialize().
- A game's abstract Entity class handles update loop integration while leaving render() to each concrete entity type.
- A payment processor abstract class enforces that every subclass implements charge() with a consistent signature.
More examples
Abstract class with abstract method
The abstract method area() has no implementation in Shape; Circle must provide one, and the shared describe() uses it.
abstract class Shape {
abstract area(): number; // must be implemented
describe(): string {
return `This shape has area ${this.area().toFixed(2)}`;
}
}
class Circle extends Shape {
constructor(private radius: number) { super(); }
area(): number { return Math.PI * this.radius ** 2; }
}
const c = new Circle(5);
console.log(c.describe());Cannot instantiate abstract class
TypeScript prevents direct instantiation of abstract classes; only concrete subclasses that implement all abstract methods can be created.
abstract class Vehicle {
abstract fuelType(): string;
move(): void { console.log('vroom'); }
}
// const v = new Vehicle(); // Error: Cannot create an instance of an abstract class
class ElectricCar extends Vehicle {
fuelType(): string { return 'electric'; }
}
const car = new ElectricCar();
car.move();Abstract class as parameter type
Uses the abstract class as a parameter type so any concrete subclass can be passed, enabling runtime polymorphism.
abstract class Logger {
abstract format(msg: string): string;
log(msg: string): void {
console.log(this.format(msg));
}
}
class JsonLogger extends Logger {
format(msg: string): string { return JSON.stringify({ msg }); }
}
function run(logger: Logger): void {
logger.log('started');
}
run(new JsonLogger());
Discussion