Inheritance & Polymorphism
The problem
Many types share common behavior and differ only in specific details — writing every method fresh for each one duplicates the shared parts, and treating each type as unrelated to the others makes it impossible to write code that works generically across all of them.
Why now
Object-oriented programming basics established the class as a unit of data and behavior; inheritance and polymorphism are how classes relate to each other — and JavaScript's prototype chain already showed one concrete implementation of 'delegate to a shared definition,' which is the exact mechanism classical inheritance formalizes with an explicit class hierarchy.
Mental model
Inheritance lets a subclass reuse a superclass's behavior and override only what differs — the same delegate-up-the-chain idea prototypes-and-inheritance already covered, just with an explicit, named hierarchy instead of an implicit link. Polymorphism is the payoff: code written against the general type (Shape) works correctly on any specific subtype (Circle, Square) without knowing which one it's holding, because each overrides area() with its own correct behavior.
Requires
- Object-Oriented Programming BasicsLow-Level Design
Inheritance relates one class to another; you need a single class already defined — data plus behavior — before a relationship between two classes has anything to connect.
- Prototypes & InheritanceJavaScript Runtime
Classical inheritance's delegate-to-a-shared-definition behavior is the same mechanism JavaScript's prototype chain already implements concretely; that real, hands-on version makes the more abstract class-hierarchy version immediately recognizable.
Unlocks
Used in
- Class hierarchies across every mainstream object-oriented language
- Interface-based polymorphism (Java interfaces, C# interfaces, TypeScript structural typing)
- Framework extension points that rely on overriding a base class's behavior
- The behavioral design patterns later in this domain (Strategy, State), which are built almost entirely on polymorphism
Projects
- Design a Shape base class with Circle, Rectangle, and Triangle subclasses, each overriding an area() method, and write one function that computes total area over a mixed list of shapes without any type-checking
- Deliberately misuse inheritance (subclass something it shouldn't be, e.g. Square extends Rectangle) and identify the resulting bug, then discuss composition-over-inheritance as a way to see the fix
Examples
- A List<Shape> can hold Circles and Squares interchangeably; calling shape.area() on each runs the correct, type-specific implementation automatically
- A Square that inherits from Rectangle and overrides setWidth to also change height silently breaks any code that assumed a Rectangle's width and height could vary independently — a classic inheritance misuse
Resources
Mastery checklist
- I can design a base class and subclasses that correctly override shared behavior
- I can write polymorphic code that operates on a base type without knowing the specific subtype
- I can explain the relationship between class-based inheritance and JavaScript's prototype chain
- I can identify a case where inheritance is being misused to model a relationship that isn't truly 'is-a'