OOP Interview Prep
Inheritance

Types of Inheritance

Single, Multilevel, Hierarchical, Multiple, and Hybrid

LinkedIn Hook

Most developers know that inheritance means "a child class gets stuff from a parent class."

Very few can answer this interview question cleanly:

"List all five types of inheritance. Explain which ones JavaScript supports natively, which ones it doesn't, and how you'd simulate the ones it doesn't."

That question has three parts. Candidates who only know single inheritance get the first part right, then fall silent.

Here's the pattern most answers follow: "Single inheritance is when a class extends one parent. Multiple inheritance is when... uh... JavaScript doesn't support that. Hybrid is... kind of like multiple?"

That's not wrong. It's just incomplete. Interviewers at mid-level and above are testing whether you understand inheritance topologies — not just that you can type extends.

Lesson 4.2 covers all five types with real JS code, ASCII diagrams, and the honest answer about which ones JS handles natively vs which ones require a workaround.

Read the full lesson -> [link]

#OOP #JavaScript #Inheritance #InterviewPrep #SoftwareEngineering


Types of Inheritance thumbnail


What You'll Learn

  • The exact definition and structure of all five inheritance types: Single, Multilevel, Hierarchical, Multiple, and Hybrid
  • ASCII diagrams for each type so you can sketch them on a whiteboard during interviews
  • Working JavaScript code for every type JS supports natively
  • How JS handles (or doesn't handle) multiple inheritance, and the mixin workaround pattern
  • The hybrid inheritance pattern built from mixins in JS
  • The most common interview traps around inheritance types

The Analogy — Family Trees Come in Different Shapes

Think about family trees. The simplest tree has one parent and one child: a grandmother passing down a recipe to a single daughter. That's single inheritance.

Now that daughter teaches her own child, who teaches her child: three generations in a straight line. That's multilevel inheritance.

A grandfather with four children — one recipe source, four inheritors — is hierarchical inheritance. One parent, many children.

Multiple inheritance is two parents passing traits to one child: a child who inherits their mother's eye color AND their father's height. Possible in real life, but complicated in code.

Hybrid inheritance mixes these patterns. A family tree with both branching and merging — some children have one parent, some have two, some share grandparents through different paths. Real family trees look like this. OOP class hierarchies sometimes do too.

[INTERNAL-LINK: what inheritance means and the extends keyword → Lesson 4.1: Inheritance Basics]


Type 1 — What Is Single Inheritance?

Single inheritance is the simplest form: one child class extends exactly one parent class. The child gets all the parent's public and protected members. It adds its own. Nothing else is involved. JavaScript supports this natively with the extends keyword.

SINGLE INHERITANCE — DIAGRAM
------------------------------
     Animal
       |
       | extends
       |
      Dog
------------------------------
One parent. One child.
The child inherits from exactly one class.
// Single inheritance: Dog extends Animal
class Animal {
  constructor(name) {
    this.name = name;
  }

  // Shared behavior — every animal can breathe
  breathe() {
    console.log(`${this.name} is breathing`);
  }

  // Shared behavior — every animal makes a sound
  makeSound() {
    console.log(`${this.name} makes a sound`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // call the parent constructor first
    this.breed = breed;
  }

  // Dog-specific behavior — inherited from Animal: breathe(), makeSound()
  fetch() {
    console.log(`${this.name} fetches the ball`);
  }

  // Override parent method — Dog has a specific sound
  makeSound() {
    console.log(`${this.name} barks`);
  }
}

const dog = new Dog("Rex", "Labrador");

dog.breathe();    // Output: Rex is breathing       (inherited from Animal)
dog.makeSound();  // Output: Rex barks              (overridden in Dog)
dog.fetch();      // Output: Rex fetches the ball   (Dog's own method)

console.log(dog instanceof Dog);    // true
console.log(dog instanceof Animal); // true — Dog is-a Animal

[PERSONAL EXPERIENCE]: In every codebase I've maintained, single inheritance accounts for the vast majority of inheritance usage. It's clear, predictable, and has no ambiguity about which parent a method comes from. The other types are worth knowing, but this is the one you'll write 90% of the time.


Type 2 — What Is Multilevel Inheritance?

Multilevel inheritance creates a chain: a child class extends a parent class, and that parent class itself extends a grandparent class. The chain can continue as many levels deep as needed. Every level inherits everything from all levels above it. JavaScript supports this natively.

MULTILEVEL INHERITANCE — DIAGRAM
----------------------------------
    LivingThing
         |
         | extends
         |
       Animal
         |
         | extends
         |
        Dog
----------------------------------
A chain of inheritance.
Dog inherits from Animal.
Animal inherits from LivingThing.
Dog gets everything from both.
// Multilevel inheritance: three levels deep
class LivingThing {
  constructor(name) {
    this.name = name;
    this.alive = true;
  }

  // All living things can grow
  grow() {
    console.log(`${this.name} is growing`);
  }

  // All living things need energy
  consumeEnergy() {
    console.log(`${this.name} is consuming energy`);
  }
}

class Animal extends LivingThing {
  constructor(name, legCount) {
    super(name); // pass name up to LivingThing
    this.legCount = legCount;
  }

  // Animals can move — plants (also LivingThing) generally can't
  move() {
    console.log(`${this.name} is moving on ${this.legCount} legs`);
  }

  breathe() {
    console.log(`${this.name} is breathing`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name, 4); // Dogs always have 4 legs
    this.breed = breed;
  }

  fetch() {
    console.log(`${this.name} (${this.breed}) fetches the ball`);
  }
}

const dog = new Dog("Rex", "Labrador");

// Method from LivingThing (two levels up)
dog.grow();           // Output: Rex is growing
dog.consumeEnergy();  // Output: Rex is consuming energy

// Method from Animal (one level up)
dog.move();           // Output: Rex is moving on 4 legs
dog.breathe();        // Output: Rex is breathing

// Dog's own method
dog.fetch();          // Output: Rex (Labrador) fetches the ball

// instanceof works at every level
console.log(dog instanceof Dog);          // true
console.log(dog instanceof Animal);       // true
console.log(dog instanceof LivingThing);  // true

Types of Inheritance visual 1

[INTERNAL-LINK: method resolution order in multilevel chains → Lesson 4.3: Multilevel Inheritance]


Type 3 — What Is Hierarchical Inheritance?

Hierarchical inheritance is the mirror pattern: one parent class, multiple child classes. Each child independently extends the same parent and inherits the same base. The children share an ancestor but are otherwise unrelated to each other. JavaScript supports this natively and uses it constantly.

HIERARCHICAL INHERITANCE — DIAGRAM
-------------------------------------
            Animal
           /  |  \
          /   |   \
       Dog   Cat  Bird
-------------------------------------
One parent. Multiple children.
Each child inherits independently from Animal.
Dog, Cat, and Bird are siblings — not related to each other.
// Hierarchical inheritance: three children from one parent
class Animal {
  constructor(name) {
    this.name = name;
  }

  breathe() {
    console.log(`${this.name} is breathing`);
  }

  // Default sound — each child will override this
  makeSound() {
    console.log(`${this.name} makes a sound`);
  }
}

class Dog extends Animal {
  makeSound() {
    console.log(`${this.name} barks`);
  }

  fetch() {
    console.log(`${this.name} fetches`);
  }
}

class Cat extends Animal {
  makeSound() {
    console.log(`${this.name} meows`);
  }

  purr() {
    console.log(`${this.name} purrs`);
  }
}

class Bird extends Animal {
  constructor(name, canFly) {
    super(name);
    this.canFly = canFly;
  }

  makeSound() {
    console.log(`${this.name} chirps`);
  }

  fly() {
    if (this.canFly) {
      console.log(`${this.name} is flying`);
    } else {
      console.log(`${this.name} cannot fly`);
    }
  }
}

const dog = new Dog("Rex");
const cat = new Cat("Whiskers");
const bird = new Bird("Tweety", true);
const penguin = new Bird("Pingu", false);

// All share inherited breathe()
dog.breathe();     // Output: Rex is breathing
cat.breathe();     // Output: Whiskers is breathing
bird.breathe();    // Output: Tweety is breathing

// Each overrides makeSound() differently
dog.makeSound();   // Output: Rex barks
cat.makeSound();   // Output: Whiskers meows
bird.makeSound();  // Output: Tweety chirps

// Each has its own unique method
dog.fetch();       // Output: Rex fetches
cat.purr();        // Output: Whiskers purrs
bird.fly();        // Output: Tweety is flying
penguin.fly();     // Output: Pingu cannot fly

// Polymorphism — treat all as Animal
const animals = [dog, cat, bird];
animals.forEach(a => a.makeSound());
// Output:
// Rex barks
// Whiskers meows
// Tweety chirps

[UNIQUE INSIGHT]: Hierarchical inheritance is the natural home of polymorphism. When you have one parent and several children that each override the same method, you unlock the ability to hold a mixed array of child instances and call that method uniformly. This is the "many forms" in polymorphism — the same method call producing different results depending on the actual object type at runtime.


Type 4 — What Is Multiple Inheritance (and Why JS Doesn't Support It)?

Multiple inheritance means one class inherits from two or more parent classes simultaneously. The child gets all members from every parent. Most classical OOP languages avoid it because of the diamond problem: if both parents define the same method, the child has two conflicting versions, and the language must pick one. JavaScript does not support multiple class inheritance natively.

MULTIPLE INHERITANCE — DIAGRAM
--------------------------------
    Flyable     Swimmable
        \          /
         \        /
          \      /
           Duck
--------------------------------
Two parents. One child.
Duck inherits from both Flyable AND Swimmable.
NOT supported with `extends` in JavaScript.
JavaScript workaround: mixins.
// Multiple inheritance is NOT possible with extends in JavaScript
// This would throw a SyntaxError:
// class Duck extends Flyable, Swimmable { }  // INVALID

// The JavaScript workaround: mixin pattern
// Mixins are plain functions that copy methods onto a target class

// Mixin 1 — Flyable behavior
const FlyableMixin = (Base) => class extends Base {
  fly() {
    console.log(`${this.name} is flying`);
  }

  getLandingSpeed() {
    return 20; // km/h
  }
};

// Mixin 2 — Swimmable behavior
const SwimmableMixin = (Base) => class extends Base {
  swim() {
    console.log(`${this.name} is swimming`);
  }

  getDiveDepth() {
    return 5; // meters
  }
};

// Base class
class Animal {
  constructor(name) {
    this.name = name;
  }

  breathe() {
    console.log(`${this.name} is breathing`);
  }
}

// Apply both mixins — compose the behaviors onto Animal
// Read right to left: Animal -> FlyableMixin -> SwimmableMixin -> Duck
class Duck extends SwimmableMixin(FlyableMixin(Animal)) {
  makeSound() {
    console.log(`${this.name} quacks`);
  }
}

// A Submarine only gets SwimmableMixin
class Submarine extends SwimmableMixin(class { constructor(id) { this.name = id; } }) {
  dive() {
    console.log(`${this.name} is diving deep`);
  }
}

const duck = new Duck("Donald");

duck.breathe();          // Output: Donald is breathing    (from Animal)
duck.fly();              // Output: Donald is flying       (from FlyableMixin)
duck.swim();             // Output: Donald is swimming     (from SwimmableMixin)
duck.makeSound();        // Output: Donald quacks          (Duck's own method)
console.log(duck.getLandingSpeed()); // Output: 20
console.log(duck.getDiveDepth());    // Output: 5

const sub = new Submarine("USS-101");
sub.swim();  // Output: USS-101 is swimming
sub.dive();  // Output: USS-101 is diving deep

// instanceof only checks the prototype chain
console.log(duck instanceof Animal); // true
console.log(duck instanceof Duck);   // true
// There is no FlyableMixin "class" to check against — it's a function

Types of Inheritance visual 2

[INTERNAL-LINK: the diamond problem explained in full → Lesson 4.4: Multiple Inheritance and The Diamond Problem]


Type 5 — What Is Hybrid Inheritance?

Hybrid inheritance combines two or more types of inheritance in the same class hierarchy. A real hierarchy might be multilevel in one branch and hierarchical in another, with a mixin stitching two branches together. It's not a new "type" by itself — it's a description of a hierarchy that doesn't fit cleanly into one single pattern.

HYBRID INHERITANCE — DIAGRAM
-------------------------------
          LivingThing
               |
             Animal          (Multilevel: LivingThing -> Animal)
            /      \
          Dog      Bird      (Hierarchical: Animal -> Dog, Bird)
                    |
              FlyingBird     (Single: Bird -> FlyingBird)
                + FlyableMixin applied
-------------------------------
This hierarchy uses:
  - Multilevel (LivingThing -> Animal)
  - Hierarchical (Animal -> Dog, Animal -> Bird)
  - Single (Bird -> FlyingBird)
  - Mixin (FlyableMixin added to FlyingBird)
= Hybrid
// Hybrid inheritance — multiple patterns in one hierarchy

const FlyableMixin = (Base) => class extends Base {
  fly() {
    console.log(`${this.name} is soaring through the air`);
  }
};

// Level 1 — root
class LivingThing {
  constructor(name) {
    this.name = name;
    this.alive = true;
  }

  grow() {
    console.log(`${this.name} grows`);
  }
}

// Level 2 — multilevel from LivingThing
class Animal extends LivingThing {
  constructor(name) {
    super(name);
  }

  breathe() {
    console.log(`${this.name} breathes`);
  }

  makeSound() {
    console.log(`${this.name} makes a sound`);
  }
}

// Level 3 — hierarchical branches from Animal
class Dog extends Animal {
  makeSound() {
    console.log(`${this.name} barks`);
  }
}

class Bird extends Animal {
  makeSound() {
    console.log(`${this.name} chirps`);
  }
}

// Level 4 — single inheritance from Bird + FlyableMixin applied
class FlyingBird extends FlyableMixin(Bird) {
  constructor(name, wingspan) {
    super(name);
    this.wingspan = wingspan;
  }

  describe() {
    console.log(`${this.name} — wingspan: ${this.wingspan}cm`);
  }
}

const dog = new Dog("Rex");
const sparrow = new FlyingBird("Sparrow", 22);

// Dog inherits through: Dog -> Animal -> LivingThing
dog.grow();       // Output: Rex grows              (LivingThing)
dog.breathe();    // Output: Rex breathes           (Animal)
dog.makeSound();  // Output: Rex barks              (Dog override)

// FlyingBird inherits through: FlyingBird -> FlyableMixin -> Bird -> Animal -> LivingThing
sparrow.grow();       // Output: Sparrow grows
sparrow.breathe();    // Output: Sparrow breathes
sparrow.makeSound();  // Output: Sparrow chirps     (Bird override)
sparrow.fly();        // Output: Sparrow is soaring through the air  (mixin)
sparrow.describe();   // Output: Sparrow — wingspan: 22cm

// Penguin is a Bird that cannot fly — single inheritance, no mixin
class Penguin extends Bird {
  makeSound() {
    console.log(`${this.name} honks`);
  }

  swim() {
    console.log(`${this.name} swims powerfully`);
  }
}

const penguin = new Penguin("Pingu");
penguin.breathe();    // Output: Pingu breathes
penguin.makeSound();  // Output: Pingu honks
penguin.swim();       // Output: Pingu swims powerfully
// penguin.fly() does not exist — Penguin didn't get the FlyableMixin

[PERSONAL EXPERIENCE]: The hybrid pattern shows up in larger production codebases more than any other type. You'll rarely plan a hybrid hierarchy from the start. It grows organically as you add features. A flat hierarchy becomes multilevel as shared logic is extracted. A single child becomes hierarchical as new child classes are added. Recognizing the type you have helps you reason about method resolution and avoid accidental method shadowing.


All Five Types at a Glance

TYPES OF INHERITANCE — SUMMARY TABLE
----------------------------------------------------------------------
Type            Structure           JS Native?   Common Use
----------------------------------------------------------------------
Single          A -> B              Yes          Most inheritance
                One parent,                      in everyday code
                one child

Multilevel      A -> B -> C         Yes          Deep specialization
                A chain of                        (LivingThing ->
                ancestors                         Animal -> Dog)

Hierarchical    A -> B              Yes          Polymorphism:
                A -> C                           one base, many
                A -> D                           specialized types
                One parent,
                many children

Multiple        A + B -> C          No           Behavior mixing
                Two parents,        (use mixins) from unrelated
                one child                        sources

Hybrid          Mix of above        Partial      Real-world
                types in one        (mixins for  growing class
                hierarchy           multiple     hierarchies
                                    parts)
----------------------------------------------------------------------

Types of Inheritance visual 3


Common Mistakes

  • Confusing multilevel with hierarchical. Multilevel is a single chain going deeper: A extends B extends C. Hierarchical is one parent branching out to many children: B extends A, C extends A, D extends A. The shapes are opposite. On a whiteboard, multilevel looks like a vertical line; hierarchical looks like a tree spreading out.

  • Thinking multiple inheritance is impossible in JavaScript. It's not supported natively with extends, but the mixin pattern replicates the behavior cleanly. Most production JS codebases that need multiple inheritance use mixins. The distinction interviewers want is: "I know JS doesn't support it syntactically, and here is the pattern I'd use instead."

  • Assuming deep multilevel hierarchies are good design. They aren't automatically. A five-level inheritance chain is usually a sign that composition would serve better. Each added level increases coupling and makes method resolution harder to follow. Lesson 4.6 covers the "favor composition over inheritance" principle in full.

  • Applying multiple mixins without checking for method name collisions. When two mixins define the same method name, the last mixin applied wins silently. There's no warning. This is the JS equivalent of the diamond problem. Always check mixin method names for overlap before combining them.

  • Forgetting that instanceof doesn't work on mixins. Because mixins are functions that return anonymous classes, there is no named constructor to check against. duck instanceof Flyable will return false even though the duck has all Flyable methods. If you need type checks, use duck typing: check for the method's existence directly (typeof duck.fly === 'function').


Interview Questions

Q: Name all five types of inheritance and briefly describe each. Single: one parent, one child. Multilevel: a chain where child extends parent, and that parent itself extends another class. Hierarchical: one parent, multiple children each extending it independently. Multiple: one child inherits from two or more parents simultaneously. Hybrid: a combination of two or more of the above types in one class hierarchy.

Q: Does JavaScript support multiple inheritance? How do you simulate it? JavaScript does not support multiple inheritance with the extends keyword. A class can only extend one other class. The standard workaround is the mixin pattern: a mixin is a function that takes a base class and returns a new class with additional methods mixed in. You chain mixins: class Duck extends SwimmableMixin(FlyableMixin(Animal)) {}. Each mixin adds its methods to the prototype chain without requiring multiple parents.

Q: What is the diamond problem, and which inheritance type causes it? The diamond problem occurs with multiple inheritance when two parent classes both inherit from the same grandparent and both override the same method. The child class inheriting from both parents has ambiguity: which parent's version of the method does it inherit? In a diamond shape on a diagram, the grandparent is at the top, two parents form the sides, and the child is at the bottom — hence "diamond." JavaScript avoids the problem by not supporting multiple class inheritance natively. The mixin pattern sidesteps it by using a linear chain rather than true multiple parents.

Q: What is the difference between multilevel and hierarchical inheritance? Multilevel inheritance is a vertical chain: class C extends class B, which extends class A. It creates depth — one line of descendants going deeper. Hierarchical inheritance is a horizontal spread: classes B, C, and D all independently extend class A. It creates breadth — one ancestor serving many children. A hierarchy can be both multilevel and hierarchical at the same time, which is one form of hybrid inheritance.

Q: Is hybrid inheritance a specific type of its own, or a combination? Hybrid inheritance is a combination, not a standalone type. It describes a class hierarchy that uses more than one inheritance type. For example, a hierarchy that is multilevel in one branch and hierarchical in another is hybrid. It's a descriptive label for real-world complex hierarchies, not a distinct mechanism. In JavaScript, hybrid hierarchies often appear naturally as codebases grow and are extended over time.


Quick Reference Cheat Sheet

TYPES OF INHERITANCE — QUICK REFERENCE
----------------------------------------------------------------------
TYPE            SHAPE               JS SYNTAX
----------------------------------------------------------------------
Single          A -> B              class B extends A {}

Multilevel      A -> B -> C         class B extends A {}
                                    class C extends B {}

Hierarchical    A -> B              class B extends A {}
                A -> C              class C extends A {}
                A -> D              class D extends A {}

Multiple        A + B -> C          NOT native in JS
                (two parents)       WORKAROUND — mixin pattern:
                                    const MixA = (Base) =>
                                      class extends Base { ... };
                                    class C extends MixA(B) {}

Hybrid          Mix of types        Combine above patterns
                in one hierarchy    in one class tree
----------------------------------------------------------------------

MIXIN PATTERN (multiple inheritance workaround in JS)
----------------------------------------------------------------------
// Define mixin as a function returning a class
const FlyableMixin = (Base) => class extends Base {
  fly() { ... }
};

const SwimmableMixin = (Base) => class extends Base {
  swim() { ... }
};

// Apply multiple mixins (chain them)
class Duck extends SwimmableMixin(FlyableMixin(Animal)) { ... }

// Duck prototype chain:
// Duck -> SwimmableMixin(class) -> FlyableMixin(class) -> Animal -> Object
----------------------------------------------------------------------

INSTANCEOF WITH MIXINS
----------------------------------------------------------------------
  duck instanceof Duck       // true
  duck instanceof Animal     // true
  duck instanceof Flyable    // false — no named constructor to check

  // Use duck typing instead:
  typeof duck.fly === 'function'   // true
  typeof duck.swim === 'function'  // true
----------------------------------------------------------------------

WHICH TYPE TO USE — QUICK GUIDE
----------------------------------------------------------------------
  One class needs one parent's features?     -> Single
  Building a specialization chain?           -> Multilevel
  One base, many specialized types?          -> Hierarchical
  Behaviors from two unrelated sources?      -> Mixin (Multiple)
  Real hierarchy grown over time?            -> Likely Hybrid
----------------------------------------------------------------------

Types of Inheritance visual 4


Previous: Lesson 4.1 - Inheritance Basics Next: Lesson 4.3 - Multilevel Inheritance


This is Lesson 4.2 of the OOP Interview Prep Course — 8 chapters, 41 lessons.

On this page