Polymorphism

JavaScript Polymorphism Tutorial

Table of Contents

  1. Introduction to Polymorphism

  2. What is Polymorphism in JavaScript?

  3. Benefits of Polymorphism

  4. Implementing Polymorphism Using Method Overriding

  5. Implementing Polymorphism Using Interfaces (Conceptual)

  6. Polymorphism in ES6 Classes

  7. Practical Examples

    • Basic Polymorphism with Method Overriding

    • Real-World Example: Shapes and Areas

    • Polymorphism with Inheritance

  8. Polymorphism in Real-World Applications

  9. Conclusion


1. Introduction to Polymorphism

Welcome to the Codes with Pankaj tutorial on Polymorphism in JavaScript! In this tutorial, we'll explore the concept of polymorphism in object-oriented programming (OOP) and how it can be implemented in JavaScript. Polymorphism allows objects of different classes to be treated as objects of a common superclass, enabling flexible and reusable code. Let’s dive in!

2. What is Polymorphism in JavaScript?

Polymorphism is a concept in object-oriented programming that allows objects of different types to be treated as instances of the same class through a common interface. In JavaScript, polymorphism is typically achieved through method overriding, where different classes provide their own implementation of a method inherited from a parent class.

In simpler terms, polymorphism allows you to use a single method name in different contexts, where the actual behavior depends on the object that is calling the method.

3. Benefits of Polymorphism

  • Code Reusability: Polymorphism allows you to reuse code and make it more generic, reducing redundancy.

  • Flexibility: It provides flexibility in code design, allowing objects to be treated in a consistent way regardless of their specific class.

  • Maintainability: Polymorphism makes code easier to maintain by decoupling the implementation details from the interface.

4. Implementing Polymorphism Using Method Overriding

Method overriding is the most common way to achieve polymorphism in JavaScript. A subclass provides its own implementation of a method that is already defined in its parent class.

Example:

class Animal {
    speak() {
        console.log("The animal makes a sound.");
    }
}

class Dog extends Animal {
    speak() {
        console.log("The dog barks.");
    }
}

class Cat extends Animal {
    speak() {
        console.log("The cat meows.");
    }
}

let animals = [new Dog(), new Cat()];

animals.forEach(animal => {
    animal.speak();  // Output: "The dog barks." and "The cat meows."
});

In this example, the speak method is overridden in the Dog and Cat classes. The speak method behaves differently depending on the object that calls it, demonstrating polymorphism.

5. Implementing Polymorphism Using Interfaces (Conceptual)

While JavaScript does not have a formal interface mechanism like other languages (e.g., Java, C#), you can conceptually implement interfaces by ensuring that different classes follow a common structure.

Example:

class Shape {
    area() {
        throw "Area method must be implemented";
    }
}

class Rectangle extends Shape {
    constructor(width, height) {
        super();
        this.width = width;
        this.height = height;
    }

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

class Circle extends Shape {
    constructor(radius) {
        super();
        this.radius = radius;
    }

    area() {
        return Math.PI * this.radius * this.radius;
    }
}

let shapes = [new Rectangle(10, 5), new Circle(7)];

shapes.forEach(shape => {
    console.log(shape.area());  // Output: 50 and 153.93804002589985
});

In this example, both Rectangle and Circle implement the area method, ensuring they follow the same interface.

6. Polymorphism in ES6 Classes

Polymorphism is naturally supported in ES6 classes through inheritance and method overriding. The ability to override methods in child classes and invoke them dynamically at runtime enables polymorphic behavior.

Example:

class Employee {
    calculateSalary() {
        return "Base salary calculation";
    }
}

class Manager extends Employee {
    calculateSalary() {
        return "Manager's salary calculation";
    }
}

class Developer extends Employee {
    calculateSalary() {
        return "Developer's salary calculation";
    }
}

let employees = [new Manager(), new Developer()];

employees.forEach(employee => {
    console.log(employee.calculateSalary());
    // Output:
    // Manager's salary calculation
    // Developer's salary calculation
});

In this example, each subclass provides its own implementation of the calculateSalary method, demonstrating polymorphism.

7. Practical Examples

Basic Polymorphism with Method Overriding

class Vehicle {
    start() {
        console.log("The vehicle is starting.");
    }
}

class Car extends Vehicle {
    start() {
        console.log("The car is starting.");
    }
}

class Motorcycle extends Vehicle {
    start() {
        console.log("The motorcycle is starting.");
    }
}

let vehicles = [new Car(), new Motorcycle()];

vehicles.forEach(vehicle => {
    vehicle.start();
    // Output:
    // The car is starting.
    // The motorcycle is starting.
});

Real-World Example: Shapes and Areas

class Shape {
    area() {
        throw "Area method must be implemented";
    }
}

class Square extends Shape {
    constructor(side) {
        super();
        this.side = side;
    }

    area() {
        return this.side * this.side;
    }
}

class Triangle extends Shape {
    constructor(base, height) {
        super();
        this.base = base;
        this.height = height;
    }

    area() {
        return (this.base * this.height) / 2;
    }
}

let shapes = [new Square(4), new Triangle(5, 6)];

shapes.forEach(shape => {
    console.log(shape.area());
    // Output:
    // 16
    // 15
});

Polymorphism with Inheritance

class Payment {
    process() {
        console.log("Processing payment.");
    }
}

class CreditCardPayment extends Payment {
    process() {
        console.log("Processing credit card payment.");
    }
}

class PayPalPayment extends Payment {
    process() {
        console.log("Processing PayPal payment.");
    }
}

let payments = [new CreditCardPayment(), new PayPalPayment()];

payments.forEach(payment => {
    payment.process();
    // Output:
    // Processing credit card payment.
    // Processing PayPal payment.
});

8. Polymorphism in Real-World Applications

Polymorphism is widely used in real-world applications where different classes share a common interface but provide different implementations. Examples include payment processing systems, where different payment methods (credit card, PayPal, etc.) implement a common process method, and UI component libraries, where different components share common behaviors.

9. Conclusion

In this detailed tutorial, we've explored the concept of polymorphism in JavaScript and how it can be implemented using method overriding and inheritance. Polymorphism allows for flexible and reusable code, enabling different objects to be treated uniformly through a common interface.

For more tutorials and examples, visit www.codeswithpankaj.com! Happy coding!


Last updated