JavaScript Class Inheritance


JavaScript Class Inheritance allows you to create a new class based on an existing one, inheriting its properties and methods. This is one of the core concepts of Object-Oriented Programming (OOP), enabling you to build on existing code without having to rewrite it. In this section, we will explore how class inheritance works in JavaScript and how you can use it to extend functionality in a clean and structured manner.


What is JavaScript Class Inheritance?

In JavaScript, class inheritance allows a class to inherit the properties and methods of another class. The class that is inherited from is called the parent class or superclass, and the class that inherits is called the child class or subclass.

The child class can:

  1. Access all public and protected properties and methods from the parent class.
  2. Override inherited methods to provide more specific behavior.
  3. Add new properties and methods of its own.

This provides a way to avoid redundancy in code, making it more maintainable and easier to extend.


Syntax for Class Inheritance

The inheritance in JavaScript is done using the extends keyword. The super() method is used to call the parent class’s constructor inside the child class’s constructor.

Basic Syntax:

class ParentClass {
  constructor() {
    this.parentProperty = 'I am from the parent class';
  }

  parentMethod() {
    console.log('This is a parent method');
  }
}

class ChildClass extends ParentClass {
  constructor() {
    super(); // Call the parent class constructor
    this.childProperty = 'I am from the child class';
  }

  childMethod() {
    console.log('This is a child method');
  }
}

Key Points:

  • The extends keyword defines the inheritance relationship between the parent and child class.
  • The super() method is used to call the constructor of the parent class before accessing this in the child class.

Example 1: Inheriting Properties and Methods

Let’s look at a simple example where the child class inherits both properties and methods from the parent class.

Code Example:

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

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

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

  speak() {
    console.log(`${this.name} barks.`);
  }

  displayBreed() {
    console.log(`${this.name} is a ${this.breed}.`);
  }
}

const myDog = new Dog('Buddy', 'Golden Retriever');
myDog.speak();  // Output: Buddy barks.
myDog.displayBreed();  // Output: Buddy is a Golden Retriever.

Explanation:

  • The Dog class extends the Animal class, inheriting the speak() method and name property.
  • The Dog class also has its own property (breed) and method (displayBreed()).
  • The speak() method is overridden in the child class to provide specific behavior for the Dog class.

Example 2: Using the super() Method

The super() method is used to call the constructor or methods of the parent class from the child class. This is important for initializing the properties inherited from the parent class.

Code Example:

class Vehicle {
  constructor(brand) {
    this.brand = brand;
  }

  honk() {
    console.log(`${this.brand} vehicle honks!`);
  }
}

class Car extends Vehicle {
  constructor(brand, model) {
    super(brand);  // Call the parent class constructor
    this.model = model;
  }

  displayDetails() {
    console.log(`${this.brand} ${this.model}`);
  }
}

const myCar = new Car('Toyota', 'Corolla');
myCar.honk();  // Output: Toyota vehicle honks!
myCar.displayDetails();  // Output: Toyota Corolla

Explanation:

  • The Car class inherits the honk() method from the Vehicle class.
  • The super(brand) in the Car constructor is used to initialize the brand property in the parent class (Vehicle).

Example 3: Method Overriding

Child classes can override methods from the parent class. This means that a method with the same name can be defined in the child class, changing or extending the behavior of the inherited method.

Code Example:

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

  greet() {
    console.log(`Hello, my name is ${this.name}.`);
  }
}

class Student extends Person {
  constructor(name, grade) {
    super(name);  // Initialize the parent class constructor
    this.grade = grade;
  }

  greet() {
    super.greet(); // Call the parent class greet method
    console.log(`I am in grade ${this.grade}.`);
  }
}

const student1 = new Student('Alice', 'A');
student1.greet();
// Output:
// Hello, my name is Alice.
// I am in grade A.

Explanation:

  • The Student class overrides the greet() method of the Person class.
  • super.greet() is used inside the child class method to first call the parent class’s greet() method and then extend its functionality.

Example 4: Inheriting and Adding New Methods

In JavaScript, the child class can add its own methods and properties, extending the functionality of the parent class.

Code Example:

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

  displayShape() {
    console.log(`This is a ${this.name}.`);
  }
}

class Rectangle extends Shape {
  constructor(name, width, height) {
    super(name);  // Call the parent class constructor
    this.width = width;
    this.height = height;
  }

  calculateArea() {
    return this.width * this.height;
  }
}

const rectangle = new Rectangle('Rectangle', 10, 5);
rectangle.displayShape();  // Output: This is a Rectangle.
console.log(`Area: ${rectangle.calculateArea()}`);  // Output: Area: 50

Explanation:

  • The Rectangle class inherits from the Shape class, but it also adds a new method calculateArea() specific to rectangles.

Benefits of JavaScript Class Inheritance

  • Code Reusability: By inheriting from a parent class, child classes can reuse code and avoid duplication.
  • Extensibility: Inheritance allows child classes to extend and customize the functionality of the parent class.
  • Maintainability: It’s easier to maintain and update functionality by making changes in the parent class, which automatically reflect in the child classes.