Introduction
Polymorphism is one of the four fundamental principles of Object-Oriented Programming (OOP). The word polymorphism comes from the Greek words “poly” (many) and “morph” (forms), meaning “many forms.”
In JavaScript, polymorphism allows different classes to provide their own implementation of the same method. When the same method is called on different objects, each object responds according to its own implementation.
The most common way to achieve polymorphism in JavaScript is through method overriding, where a child class overrides a method inherited from its parent class.
For automation engineers, polymorphism helps build flexible automation frameworks by allowing different page objects, browser classes, API clients, and reusable utilities to implement common methods in different ways.
In this tutorial, you’ll learn how method overriding is used to achieve polymorphism in Node.js.
What is Polymorphism?
Polymorphism allows the same method name to perform different actions depending on the object that invokes it.
This enables developers to write flexible and reusable code.
Method Overriding and Polymorphism
Method overriding is the primary mechanism used to implement runtime polymorphism in JavaScript.
A child class overrides a method inherited from the parent class, providing its own implementation.
When the overridden method is called on a child object, the child class version executes.
Why Use Polymorphism?
Polymorphism helps developers:
Write flexible code.
Improve code reusability.
Reduce code duplication.
Extend applications easily.
Improve maintainability.
Support runtime behavior changes.
Build scalable applications.
Syntax
class Parent {
display() {
console.log("Parent");
}
}
class Child extends Parent {
display() {
console.log("Child");
}
}
The child class overrides the parent method.
Example 1: Basic Polymorphism
class Animal {
sound() {
console.log(
"Animal sound."
);
}
}
class Dog extends Animal {
sound() {
console.log(
"Dog barks."
);
}
}
const dog =
new Dog();
dog.sound();
Sample Output
Dog barks.
Although the method name is sound(), the behavior changes based on the object.
Example 2: Different Child Classes
class Animal {
sound() {
console.log(
"Animal sound."
);
}
}
class Dog extends Animal {
sound() {
console.log(
"Dog barks."
);
}
}
class Cat extends Animal {
sound() {
console.log(
"Cat meows."
);
}
}
const dog =
new Dog();
const cat =
new Cat();
dog.sound();
cat.sound();
Sample Output
Dog barks.
Cat meows.
Example 3: Employee Roles
class Employee {
work() {
console.log(
"Employee working."
);
}
}
class Developer extends Employee {
work() {
console.log(
"Writing code."
);
}
}
class Tester extends Employee {
work() {
console.log(
"Testing application."
);
}
}
const developer =
new Developer();
const tester =
new Tester();
developer.work();
tester.work();
Sample Output
Writing code.
Testing application.
Example 4: Using super with Overriding
class Vehicle {
start() {
console.log(
"Vehicle started."
);
}
}
class Car extends Vehicle {
start() {
super.start();
console.log(
"Car is ready."
);
}
}
const car =
new Car();
car.start();
Sample Output
Vehicle started.
Car is ready.
Example 5: Real-World Example
Notification system.
class Notification {
send() {
console.log(
"Sending notification."
);
}
}
class EmailNotification extends Notification {
send() {
console.log(
"Sending Email."
);
}
}
class SmsNotification extends Notification {
send() {
console.log(
"Sending SMS."
);
}
}
const email =
new EmailNotification();
const sms =
new SmsNotification();
email.send();
sms.send();
Sample Output
Sending Email.
Sending SMS.
Automation Testing Example
Polymorphism is widely used in automation frameworks.
Playwright Example
Different page objects implement login differently.
class BasePage {
login() {
console.log(
"Default Login."
);
}
}
class AdminPage extends BasePage {
login() {
console.log(
"Admin Login."
);
}
}
const page =
new AdminPage();
page.login();
Selenium Example
Different browsers.
class Browser {
launch() {
console.log(
"Launching Browser."
);
}
}
class ChromeBrowser extends Browser {
launch() {
console.log(
"Launching Chrome."
);
}
}
const browser =
new ChromeBrowser();
browser.launch();
Cypress Example
Different pages.
class BaseCommands {
openPage() {
console.log(
"Opening page."
);
}
}
class DashboardPage extends BaseCommands {
openPage() {
console.log(
"Opening Dashboard."
);
}
}
const dashboard =
new DashboardPage();
dashboard.openPage();
API Testing Example
Different API endpoints.
class BaseApi {
sendRequest() {
console.log(
"Base API Request."
);
}
}
class UserApi extends BaseApi {
sendRequest() {
console.log(
"User API Request."
);
}
}
const api =
new UserApi();
api.sendRequest();
Data-Driven Testing Example
Different employee roles.
class Employee {
showRole() {
console.log(
"Employee"
);
}
}
class Manager extends Employee {
showRole() {
console.log(
"Manager"
);
}
}
const manager =
new Manager();
manager.showRole();
Common Mistakes
Changing the Method Name
Incorrect:
class Dog extends Animal {
bark() {
}
}
This is not polymorphism because the parent method is not overridden.
Forgetting Inheritance
Method overriding requires inheritance using the extends keyword.
Forgetting super When Parent Behavior Is Needed
If you want to preserve the parent method’s functionality while adding new behavior, call it using super.methodName().
Best Practices
Override methods only when behavior should differ.
Keep the same method signature.
Use meaningful class names.
Reuse parent functionality with
superwhen appropriate.Avoid unnecessary overriding.
Keep overridden methods focused and readable.
Design reusable parent classes.
Conclusion
Polymorphism allows objects of different classes to respond differently to the same method call. In JavaScript, this is commonly achieved through method overriding.
For automation engineers, polymorphism helps create flexible automation frameworks where page objects, browsers, API clients, and reusable utilities implement common methods according to their specific requirements.
Understanding polymorphism through method overriding is essential before learning advanced Object-Oriented Programming concepts and designing scalable applications.
Frequently Asked Questions (FAQs)
What is polymorphism?
Polymorphism is the ability of different objects to respond differently to the same method call.
How is polymorphism achieved in JavaScript?
Primarily through method overriding using inheritance.
What is method overriding?
Method overriding occurs when a child class provides its own implementation of a method inherited from the parent class.
Can the parent method still be used?
Yes. Use super.methodName() to call the parent method.
Why is polymorphism important in automation testing?
It allows different page objects, browser classes, API clients, and reusable components to implement common methods differently while sharing the same interface.
Key Takeaways
Polymorphism means “many forms.”
Method overriding is the primary way to achieve polymorphism in JavaScript.
Different objects can respond differently to the same method call.
Polymorphism improves flexibility and code reuse.
Use inheritance with the
extendskeyword.Use
superto reuse parent functionality when required.Polymorphism is widely used in Playwright, Selenium, Cypress, and API testing frameworks.
Keep overridden methods simple and meaningful.
Design reusable parent classes and specialized child classes.
Polymorphism is a core principle of Object-Oriented Programming in Node.js.
