Abstract Classes
In this page:
Creating an Abstract Class
An abstract class is declared with the abstract keyword and is designed to be extended, not instantiated directly — attempting new on an abstract class is a compile-time error.
Example: Creating an Abstract Class
abstract class Shape {
abstract area(): number;
}
// new Shape(); // rejected: cannot instantiate an abstract class
class Circle extends Shape {
constructor(public radius: number) { super(); }
area() { return 3.14 * this.radius ** 2; }
}
console.log(new Circle(5).area());
Abstract Methods
An abstract method has a declaration but no implementation in the abstract base class; every concrete subclass is required to supply its own implementation, which the compiler enforces.
Example: Abstract Methods
abstract class Animal {
abstract makeSound(): string;
}
class Dog extends Animal {
makeSound() { return "Woof"; }
}
console.log(new Dog().makeSound());
Concrete Methods in Abstract Classes
Abstract classes can also contain normal concrete methods alongside abstract ones, letting shared, already-working logic live in the base class while only the parts that genuinely vary are left for subclasses to fill in.
Example: Concrete Methods in Abstract Classes
abstract class Animal {
abstract makeSound(): string;
describe() {
return `This animal says: ${this.makeSound()}`;
}
}
class Cat extends Animal {
makeSound() { return "Meow"; }
}
console.log(new Cat().describe());
Abstract Classes and Polymorphism
An abstract class can be used as a type for references to different concrete subclasses, so code written against the abstract type works uniformly no matter which specific subclass is passed in at runtime.
Example: Abstract Classes and Polymorphism
abstract class Shape {
abstract area(): number;
}
class Square extends Shape {
constructor(public side: number) { super(); }
area() { return this.side ** 2; }
}
class Circle extends Shape {
constructor(public radius: number) { super(); }
area() { return 3.14 * this.radius ** 2; }
}
const shapes: Shape[] = [new Square(4), new Circle(2)];
shapes.forEach((s) => console.log(s.area()));
When to Use Abstract Classes
Abstract classes are useful when related classes share real implementation but must also provide their own version of at least one method — if there's nothing shared at all, a plain interface is usually the better fit.
Example: When to Use Abstract Classes
abstract class Employee {
constructor(public name: string) {}
abstract calculateSalary(): number;
printPaycheck() {
console.log(`${this.name}: $${this.calculateSalary()}`);
}
}
class Manager extends Employee {
calculateSalary() { return 5000; }
}
new Manager("Alia").printPaycheck();
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: