1. Introduction
An abstract class is a class that cannot be instantiated directly — it exists purely to be extended. It can define fully-implemented methods shared by all subclasses, as well as abstract methods that declare a signature without a body, forcing every concrete subclass to provide its own implementation.
Cricket analogy: You can't select 'Bowler' as a player on the team sheet — only concrete bowlers like Jasprit Bumrah or Mitchell Starc, each supplying their own run-up, while the shared 'walk back to mark' routine stays identical for all.
2. Syntax
abstract class BaseClassName {
abstract methodName(): ReturnType; // no body
concreteMethod(): void {
// shared implementation
}
}
class DerivedClassName extends BaseClassName {
methodName(): ReturnType {
// required implementation
}
}3. Explanation
The abstract keyword before class marks the class as abstract, and abstract before a method declares that method's signature without providing a body. TypeScript enforces two rules: you can never write new BaseClassName() directly, and any non-abstract subclass must implement every abstract method inherited from its base class.
Cricket analogy: Just as you can never write 'select Generic Bowler' on a scorecard, TypeScript blocks new Bowler() on an abstract class — every specific bowler like Bumrah must supply the run-up method the base class only declared.
Abstract classes are useful when several related classes share common behavior (like a describe() method) but each needs its own specialized logic for a specific operation (like calculating an area). This is a form of polymorphism: code that works with the abstract base type can call the shared method, and the correct subclass implementation runs automatically.
Cricket analogy: All-rounders share a common 'walk to the crease' routine but each has specialized batting technique — call bat() on any all-rounder like Hardik Pandya or Ben Stokes and their own specific shot execution runs automatically.
Abstract classes cannot be instantiated directly — writing new Shape() where Shape is declared abstract class Shape produces the compile-time error: "Cannot create an instance of an abstract class." You must extend the abstract class and instantiate a concrete subclass instead.
4. Example
abstract class Shape {
abstract area(): number;
describe(): string {
return `Area is ${this.area()}`;
}
}
class Circle extends Shape {
constructor(private radius: number) {
super();
}
area(): number {
return Math.PI * this.radius ** 2;
}
}
class Square extends Shape {
constructor(private side: number) {
super();
}
area(): number {
return this.side * this.side;
}
}
const shapes: Shape[] = [new Circle(2), new Square(4)];
shapes.forEach((s) => console.log(s.describe()));
// const s = new Shape();
// Error: Cannot create an instance of an abstract class.5. Output
Area is 12.566370614359172
Area is 166. Key Takeaways
- An abstract class can never be instantiated directly with 'new'.
- Abstract methods declare a signature with no body and must be implemented by every concrete subclass.
- Abstract classes can mix abstract methods with fully implemented (concrete) methods.
- Subclasses use 'extends' and must call super() before accessing 'this' in their constructor.
- Abstract classes enable polymorphism: shared base-class logic can call subclass-specific implementations.
Practice what you learned
1. What happens if you try to write `new Shape()` where Shape is declared as `abstract class Shape`?
2. What must a non-abstract subclass do when it extends an abstract class with an abstract method?
3. In the Shape example, why does shapes.forEach(s => console.log(s.describe())) work even though describe() is not overridden in Circle or Square?
4. What is the exact output of `console.log(s.describe())` for a Square constructed with side 4?
5. What must a subclass constructor call before it can access 'this' when extending a class?
Was this page helpful?
You May Also Like
Classes in TypeScript
Learn how TypeScript classes add type-checked properties, methods, and constructor parameter property shorthand on top of ES2015 classes.
Implementing Interfaces in TypeScript
Use the implements keyword to make a class satisfy an interface's compile-time contract, and understand how this differs from extending a base class.
Access Modifiers in TypeScript (public, private, protected)
Control the visibility of class members with public, private, and protected, and understand that these checks exist only at compile time.
Static Members in TypeScript
Define properties and methods that belong to the class itself rather than to individual instances, using the static keyword.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics