JavaScript > Prototypes and Inheritance > Constructor Functions and Classes > Class inheritance (extends)

Extending Classes in JavaScript

Learn how to create new classes based on existing ones using the extends keyword in JavaScript. This example demonstrates class inheritance, allowing you to reuse and extend functionality from parent classes.

Introduction to Class Inheritance

Class inheritance is a fundamental concept in object-oriented programming (OOP) that allows you to create new classes (child classes or subclasses) based on existing classes (parent classes or superclasses). The child class inherits properties and methods from the parent class and can also add its own properties and methods or override inherited ones. In JavaScript, the extends keyword is used to implement class inheritance.

Basic Class Inheritance Example

In this example, we define a parent class Animal with a constructor and a speak method. We then create a child class Dog that inherits from Animal using the extends keyword. The Dog class has its own constructor, which calls the parent class constructor using super(name). It also overrides the speak method and adds a new method wagTail. The output shows how the child class inherits and overrides methods from the parent class.

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

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

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

  speak() {
    console.log(`${this.name} barks.`); // Override the speak method
  }

  wagTail() {
    console.log(`${this.name} wags its tail.`);
  }
}

// Creating instances
const animal = new Animal('Generic Animal');
animal.speak(); // Output: Generic Animal makes a sound.

const dog = new Dog('Buddy', 'Golden Retriever');
dog.speak(); // Output: Buddy barks.
dog.wagTail(); // Output: Buddy wags its tail.

The super() Keyword

The super() keyword is crucial in class inheritance. It is used to call the constructor of the parent class. When a child class has a constructor, it must call super() before accessing this. super() can also be used to call methods of the parent class from within the child class.

Concepts Behind the Snippet

This snippet showcases the core concepts of class inheritance:

  • Inheritance: The Dog class inherits properties and methods from the Animal class.
  • Extends: The extends keyword establishes the inheritance relationship.
  • Super: The super() keyword allows the child class to call the parent class's constructor and methods.
  • Overriding: The child class can override methods from the parent class to provide specific behavior.

Real-Life Use Case

Class inheritance is useful in scenarios where you have a hierarchy of objects with shared properties and behaviors. For example, you might have a base class Vehicle and subclasses like Car, Truck, and Motorcycle. Each subclass inherits common properties like make, model, and year, but can also have its own specific properties and methods like numberOfDoors for Car or cargoCapacity for Truck.

Best Practices

  • Keep Inheritance Hierarchies Shallow: Deep inheritance hierarchies can become difficult to manage and understand. Aim for shallow hierarchies with clear relationships.
  • Favor Composition Over Inheritance: In some cases, composition (combining objects as properties) can be a more flexible alternative to inheritance.
  • Use super() Correctly: Always call super() in the child class constructor before accessing this.

Interview Tip

When discussing class inheritance in an interview, be prepared to explain the benefits of inheritance, such as code reuse and improved organization. Also, be ready to discuss the trade-offs, such as increased complexity and potential for tight coupling. The difference between overriding and overloading is an important concept to master.

When to Use Them

Use class inheritance when:

  • You have a clear 'is-a' relationship between classes (e.g., a Dog 'is a' Animal).
  • You want to reuse and extend the functionality of an existing class.
  • You want to create a hierarchy of objects with shared properties and behaviors.

Memory Footprint

Inheritance can potentially increase the memory footprint of your application, especially with deep inheritance hierarchies. Each instance of a child class contains all the properties and methods of its parent classes. However, the memory overhead is usually negligible compared to the benefits of code reuse and organization.

Alternatives

Alternatives to class inheritance include:

  • Composition: Combining objects as properties instead of inheriting from them.
  • Mixins: Providing reusable functionality by mixing in properties and methods from other objects.
  • Functional Programming: Using pure functions and avoiding mutable state to achieve code reuse and organization.

Pros

  • Code Reuse: Inheritance allows you to reuse code from parent classes, reducing duplication.
  • Organization: Inheritance helps organize code into a hierarchy of classes, making it easier to understand and maintain.
  • Polymorphism: Inheritance enables polymorphism, allowing objects of different classes to be treated as objects of a common type.

Cons

  • Complexity: Deep inheritance hierarchies can become complex and difficult to manage.
  • Tight Coupling: Inheritance can create tight coupling between classes, making it harder to modify or reuse code.
  • Fragile Base Class Problem: Changes to the parent class can have unintended consequences in child classes.

FAQ

  • What is the difference between extends and super() in JavaScript?

    extends is used to create a subclass from a parent class, inheriting its properties and methods. super() is used within the subclass's constructor to call the constructor of the parent class and initialize its properties. It must be called before accessing this in the subclass constructor.
  • Can a class inherit from multiple classes in JavaScript?

    No, JavaScript does not support multiple inheritance in the traditional sense. A class can only inherit directly from one parent class using extends. However, you can achieve similar results using composition or mixins.
  • What is method overriding?

    Method overriding is when a subclass provides its own implementation of a method that is already defined in its parent class. When the method is called on an instance of the subclass, the subclass's implementation is executed instead of the parent class's implementation.