The inheritance is a feature that allows creating new classes based on existing classes.
With inheritance, a class can have the properties and methods of another, while adding or overriding with its own methods.
This relationship between classes is known as parent-child or superclass-subclass relationship.
In JavaScript, inheritance is primarily implemented through classes, which were introduced in ECMAScript 6 (ES6).
Before ES6, JavaScript used constructor functions and the prototype
object to implement inheritance. With the introduction of class syntax, inheritance became simpler and clearer.
If you want to learn more, you can check out
Basic Syntax of Inheritance
In JavaScript, to create a subclass that inherits from the base class, we use the keyword extends
.
First, we need to define a base class, and then we would create the derived class. For example, like this:
class Animal {
constructor(name) {
this.name = name; // Shared property
}
speak() {
console.log(`${this.name} makes a sound`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // Calls the constructor of the parent class
this.breed = breed; // Additional property
}
speak() {
console.log(`${this.name} says Woof!`);
}
}
const myDog = new Dog('Rex', 'Labrador');
myDog.speak(); // "Rex says Woof!"
In this example:
Animal
is the base class that has a constructor that assigns a value toname
and a method calledspeak()
.Dog
is a subclass that inherits fromAnimal
. It uses thesuper()
method to call the constructor of the base class and assign the value toname
.- Additionally, it overrides the
speak()
method to customize the specific behavior of dogs.
Super Keyword
The super()
keyword allows us to get a reference to the base class from the derived class. For example, it is used to:
- Call the superclass constructor: When we need to initialize inherited properties from the base class.
- Access superclass methods: To use methods from the superclass within the subclass.
class Dog extends Animal {
constructor(name, breed) {
super(name); // Calls the constructor of the parent class
this.breed = breed; // Additional property
}
}
In the previous example,
super(name)
calls the constructor ofAnimal
and passes the argumentname
so that thename
property is initialized.
Inherited Properties and Methods
When a subclass inherits from a superclass, it inherits its properties and methods. This means we can access the properties and methods of the superclass as if they were defined directly in the subclass.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound`);
}
}
class Cat extends Animal {
// No need to redefine 'name', as it is inherited from Animal
}
const myCat = new Cat('Whiskers');
myCat.speak(); // "Whiskers makes a sound"
Here, Cat
inherits the speak()
method from Animal
and can use it without having to redefine it.
Overriding Methods in the Subclass
One feature of inheritance is that we can override the methods of the base class in the subclass. This allows us to customize the behavior.
This is useful when we want subclasses to have specific behaviors while retaining the foundation of the original class.
class Cat extends Animal {
speak() {
console.log(`${this.name} says Meow!`);
}
}
const myCat = new Cat('Rufus the cat');
myCat.speak(); // "Rufus the cat says Meow!"
In this case, Cat
redefines the speak()
method so that it makes a different sound than Animal
.
Static Properties and Inheritance
Subclasses also inherit static properties. The base class and the derived class share static variables and methods (the derived class does not have its own versions)
class Animal {
static species = 'Animal'; // Static property
//... more things
}
class Dog extends Animal {}
console.log(Dog.species); // "Animal"
Dog.species = "Doggo";
console.log(Animal.species); // "Doggo"
Here,
- The static property
species
is inherited by the subclassDog
. - If we access
Dog.species
, we getAnimal
. - When we modify
Dog.species
, we also modifyAnimal.species
. - That is, the property
species
is the same for both classes.
What is Polymorphism?
In other words, polymorphism allows objects of different classes to have different behaviors for the same method.
In JavaScript, polymorphism can be achieved using inheritance and method overriding. Let’s see it with an example:
let animal = new Animal('Animal');
let cat = new Cat('Cat');
let dog = new Dog('Dog');
animal.makeSound(); // Making sound...
cat.makeSound(); // Meow!
dog.makeSound(); // Woof!
class Animal {
constructor(name) {
this.name = name;
}
makeSound() {
console.log('Making sound...');
}
}
class Cat extends Animal {
constructor(name) {
super(name);
}
makeSound() {
console.log('Meow!');
}
}
class Dog extends Animal {
constructor(name) {
super(name);
}
makeSound() {
console.log('Woof!');
}
}
In this example,
- We have a class Animal with a method
makeSound()
. - The
Cat
class and theDog
class inherit from theAnimal
class and override themakeSound()
method with their own implementations. - When the
makeSound()
method is called on each object, the behavior is different according to the class of the object.