Menu
Coddy logo textTech

The Limits of Deep Inheritance

Part of the Object Oriented Programming section of Coddy's JavaScript journey — lesson 48 of 56.

While inheritance is useful, creating very deep inheritance hierarchies (parent → child → grandchild → great-grandchild) can lead to problems. The deeper the chain, the harder it becomes to understand, maintain, and modify the code.

Let's see what happens with a deep inheritance chain:

// Base class
class Vehicle {
  constructor(type) {
    this.type = type;
    this.isRunning = false;
  }
  
  start() {
    this.isRunning = true;
    console.log(`${this.type} started`);
  }
}

// First level of inheritance
class Car extends Vehicle {
  constructor(make, model) {
    super("Car");
    this.make = make;
    this.model = model;
    this.wheels = 4;
  }
  
  honk() {
    console.log("Beep beep!");
  }
}

// Second level of inheritance
class SportsCar extends Car {
  constructor(make, model, topSpeed) {
    super(make, model);
    this.topSpeed = topSpeed;
  }
  
  race() {
    this.start();
    console.log(`Racing at ${this.topSpeed} mph!`);
  }
}

In this example, SportsCar is two levels deep in inheritance. This can lead to several problems:

  1. Changes to Vehicle might unexpectedly break SportsCar
  1. As the inheritance chain grows, it becomes harder to track where methods and properties come from
  1. You're forced into "is-a" relationships that might not be flexible enough
challenge icon

Challenge

Complete the Robot.js file to make the robot functional. Right now, the robot is built but can't do anything.

What to do in <strong>Robot.js</strong>:

  1. Create the speaker and the mover components inside the Robot constructor
  2. Use the components in the methods:
    1. In greet(): Call this.speaker.speak("Hello!");
    2. In walkForward(): Call this.mover.move("forward");

Why we do this: This is composition - the robot is built by combining smaller components. The robot has-a speaker (for talking) and has-a mover (for moving), rather than inheriting these abilities.

Cheat sheet

Deep inheritance hierarchies (parent → child → grandchild) can lead to maintenance problems and inflexibility. The deeper the chain, the harder it becomes to understand and modify the code.

Example of a deep inheritance chain:

class Vehicle {
  constructor(type) {
    this.type = type;
    this.isRunning = false;
  }
  
  start() {
    this.isRunning = true;
    console.log(`${this.type} started`);
  }
}

class Car extends Vehicle {
  constructor(make, model) {
    super("Car");
    this.make = make;
    this.model = model;
  }
}

class SportsCar extends Car {
  constructor(make, model, topSpeed) {
    super(make, model);
    this.topSpeed = topSpeed;
  }
}

Problems with deep inheritance:

  • Changes to base classes can unexpectedly break child classes
  • Difficult to track where methods and properties originate
  • Forces rigid "is-a" relationships that lack flexibility

Composition as an alternative: Instead of inheritance, use composition where objects have-a relationship with components, combining smaller parts to build functionality.

Try it yourself

import { Robot } from './Robot.js';

const myRobot = new Robot('Robo');

myRobot.greet();     // Should output: Saying: "Hello!"
myRobot.walkForward(); // Should output: Moving forward
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming