Inheritance in JavaScript Classes

Welcome, JavaScript adventurers! In this chapter, we delve into the concept of inheritance, a cornerstone of object-oriented programming (OOP) in JavaScript. Inheritance allows you to create new classes (subclasses) that inherit properties and behaviors from existing classes (superclasses). Buckle up as we explore the fundamentals, practical applications, and advanced techniques of inheritance in JavaScript classes.

The Essence of Inheritance: Building Upon Existing Blueprints

  • Imagine you have a blueprint for a house (superclass). Inheritance allows you to create a blueprint for a specific type of house, like a bungalow (subclass), that inherits the general structure (properties) from the house blueprint but can also have its own unique features (methods).
  • In JavaScript, the extends keyword is used to establish inheritance between classes.

Creating a Class Hierarchy with Inheritance

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

  eat() {
    console.log(this.name + " is eating.");
  }
}

class Dog extends Animal { // Dog inherits from Animal (subclass)
  constructor(name, breed) {
    super(name); // Call the superclass constructor (Animal)
    this.breed = breed;
  }

  bark() {
    console.log(this.name + " is barking!");
  }
}

const dog = new Dog("Buddy", "Labrador");
dog.eat();  // Output: Buddy is eating. (inherited from Animal)
dog.bark(); // Output: Buddy is barking! (specific to Dog)

				
			

Explanation:

  • The Animal class defines a basic structure for animals with a name and an eat() method.
  • The Dog class inherits from Animal using extends.
  • The Dog constructor calls the superclass constructor (super(name)) to initialize the inherited name property.
  • Dog also has its own breed property and a specific bark() method.
  • We create a dog object instance.
  • Calling dog.eat() executes the inherited eat() method from Animal.
  • Calling dog.bark() executes the method specific to the Dog class.

Method Overriding: Specializing Inherited Behavior

  • Subclasses can override inherited methods to provide their own implementation.
				
					class Bird extends Animal {
  constructor(name, wings) {
    super(name);
    this.wings = wings;
  }

  eat() {
    console.log(this.name + " is pecking at food."); // Overridden eat() method
  }

  fly() {
    console.log(this.name + " is flying!");
  }
}

const bird = new Bird("Tweety", 2);
bird.eat();  // Output: Tweety is pecking at food. (overridden)
bird.fly();  // Output: Tweety is flying! (specific to Bird)

				
			

Explanation:

  • The Bird class inherits from Animal.
  • The Bird class overrides the eat() method with a bird-specific eating behavior.
  • The Bird class also has its own fly() method.
  • We create a bird object instance.
  • Calling bird.eat() executes the overridden eat() method from Bird.
  • Calling bird.fly() executes the method specific to the Bird class.

Understanding Polymorphism: Treating Objects Uniformly

  • Polymorphism is a key concept in OOP. It allows objects of different classes (subclasses) to respond to the same method call (if they inherited it) in different ways. This enables flexible and reusable code.
				
					function makeSound(animal) {
  animal.makeSound(); // Call the makeSound() method (assumed to be inherited)
}

const dog = new Dog("Buddy", "Labrador");
const bird = new Bird("Tweety", 2);

makeSound(dog);  // Output: Buddy is barking! (Dog's implementation of makeSound())
makeSound(bird); // Output: Tweety is chirping! (Bird's implementation, not shown here)

				
			

Explanation:

  • We define a makeSound function that expects an animal object as an argument.
  • The function assumes the animal object has a makeSound() method (inherited from a common ancestor perhaps).
  • When we call makeSound(dog), the Dog class’s bark() method is executed (assuming bark() is its implementation of `makeSound
  • When we call makeSound(bird), a bird-specific makeSound() method (not shown here) would be executed, assuming the Bird class also inherits a makeSound() method from a common ancestor.

Advanced Topics: Mixins and Multiple Inheritance (Use with Caution)

  • Mixins: These are reusable modules or classes that contain functionalities that can be easily “mixed in” to other classes without formal inheritance. Mixins promote code reusability and modularity.
				
					const Flyable = {
  fly() {
    console.log(this.name + " is flying!");
  }
};

class Bat {
  constructor(name) {
    this.name = name;
  }
}

Object.assign(Bat.prototype, Flyable); // Mixin Flyable functionality into Bat

const bat = new Bat("Echo");
bat.fly(); // Output: Echo is flying!

				
			

Explanation:

  • The Flyable object is a mixin with a fly() method.
  • We don’t use inheritance here. Instead, we use Object.assign to mix the Flyable functionality (properties and methods) into the Bat class prototype.
  • Now, Bat instances can access the fly() method from the mixin.
  • Multiple Inheritance: JavaScript doesn’t directly support multiple inheritance (inheriting from more than one parent class). However, there are workarounds using techniques like mixins or prototypal inheritance (advanced topic beyond this chapter). Due to potential complexity issues, it’s generally recommended to favor alternative approaches like composition (having objects contain instances of other classes) over multiple inheritance.

Inheritance is a powerful tool for code reusability and organization in JavaScript. By understanding how to create class hierarchies, override methods, and leverage polymorphism, you can write well-structured and maintainable object-oriented programs. Happy coding !❤️

Table of Contents

Contact here

Copyright © 2025 Diginode

Made with ❤️ in India