Prerequisite:
A good understanding of how JavaScript classes work and how to use it. Check out my blog post on Introduction to JavaScript class example and usage, if you're not familiar with how to use JavaScript classes.
Introduction
One of the most powerful features of JavaScript is its ability to support inheritance, which is one of the fundamental principle of Object-Oriented Programming (OOP).
The main concept of inheritance is the ability of a class to derive attributes and functionalities from another class, enabling the extension of class's capabilities.
Prior to ES6 Implementing a proper inheritance require multiple steps. One of the strategies used was PROTOTYPE INHERITANCE.
Class inheritance involves two part:
Parent Class (Super Class): A class whose attributes and functionalities are inherited from.
Child Class (Sub Class): A class that derives attributes and functionalities from another class.
The parent class properties and functionalities are inherited by the child class.
Why Class Inheritance?
Inheritance gives developer the ability to write less code, which saves cost and time.
Inheritance helps to extend the functionalities of a class and support code reusability.
"Any piece of useful software will sooner or later change, not necessarily because it is erroneous, but rather because it is desirable to enhance its functionalities" - Mezini, Mira.
The extends
Keyword
The extends keyword provides a class with the ability to acquire properties and methods from another class. When used to declare or define a class, it automatically turns the class into a child class. extends
helps to establish a relationship between classes.
Syntax
class ClassName extends ParentClass {
/* ... */
}
class - the keyword for defining a class
ClassName - the name child class
extends - JavaScript keyword used to extend the functionality of the parent class
ParentClass - super class whose functionality are derived from
Using the
extends
keyword on a class is the starting point for implementing inheritance.
// Parent Class
class Vehicle {
constructor(name, model){
this.name = name;
this.model = model;
}
details(){
console.log(`${this.name}, model ${this.model}`);
}
}
// Child Class
class Car extends Vehicle {
topSpeed(){
this.speed = '168mph';
console.log(`${this.name} ${this.model} maxes out at ${this.speed}`);
}
}
const suv = new Car('Tesla', 'X Plaid'); // Creating Car Object
suv.details() // Tesla, model X Plaid
suv.topSpeed(); // Tesla model X Plaid maxes out at 168mph
In the example above we, created a Vehicle class with some class members in the class body. Then we created a Car
class that extends the parent class. We defined a method where we create and initialize the top speed of the car, and then we log out the details.
In the example, the extends
keyword shows how powerful it is to extend the functionality of the super class. When used on the child class, the extends
keyword gives us the privilege to access the parent class's properties and methods, including the constructor, thereby making it become part of the child class.
Overriding
Overriding is an OOP term where a particular method in the subclass has the same name as the method in the parent class. When an instance of the subclass gets called on the method, the subclass method get implemented instead of the super class method.
Method Overriding
When we use the extends
keyword on the child class, we inherit all the methods declared on the parent class by default. Method overriding allows us to replace the code of the parent class with the child class method, given that they share the same name.
However, we don't want to actually replace the method of the parent class, but to build upon it by extending its functionality, since that's what the concept of inheritance is all about.
JavaScript provides a way to extend method functionality without completely replacing the parent class method with the use of super
keyword and super()
.
The super keyword can be used as an object or as a function look up
Overriding method using the super
The super
keyword allows us to access an overridden method of a parent class in a subclass. By using the super
keyword in a subclass method, we can extend the functionalities of the parent class method. This usage of super
treats it an object.
Syntax
super.methodName()
class Animal {
makeSound(){
console.log('Make Sound')
}
}
class Dog extends Animal {
makeSound(){
super.makeSound();
console.log('Woof! Woof!!');
}
}
const dog = new Dog();
dog.makeSound(); // Make Sound Woof! Woof!!
In the example above, we created an Animal
class which has makeSound
method. We then extend the 'Dog' class and override the makeSound
method. We call the parent class method using super
and then we log out the sound made by the dog.
Overriding constructor using super()
By default, every subclass will inherits the constructor of the parent class. When we define or declare a constructor in the subclass, we have successfully overridden the parent class constructor.
Overriding a constructor provides the subclass with its own code logic and attributes.
Using super in constructor is a slightly different. Here, the super
is used as a function call in the subclass constructor. When overriding a constructor in the subclass, the super
constructor must be called first before using this
.
A
ReferenceError
is raised ifthis
keyword is used before calling thesuper
constructorsuper()
.
class Vehicle {
constructor(brand){
this.brand = brand;
}
displayBrand(){
console.log(`Brand: ${this.brand}`);
}
}
class Car extends Vehicle{
constructor(brand, model, color){
super(brand);
this.model = model;
this.color = color;
}
displayDetails(){
console.log(`Details: ${this.model} ${this.color}`);
}
}
const car1 = new Car('Tesla', 'Model X', 'Cherry')
car1.displayBrand(); // Tesla
car1.displayDetails(); // Details: Model X Cherry
In the example above, the Vehicle
class is defined with a constructor that accepts a brand
parameter and initializes the brand
property. The displayBrand
method is defined which prints out the brand property.
The Car
class is defined and extends the Vehicle
class. The class defines its own constructor property, and the super(brand)
is used to invoke the super class constructor, with a parameter of brand
is passed in. The Car
class also has the displayDetails
method which prints out the model
and color
.
Later, an instance of the Car
is created, arguments are passed into the constructor of the Car
class, then we call displayBrand
and displayDetails
on the object instance.
The
super
keyword is used to access the properties and methods of parent class while thesuper()
is used within the constructor of a subclass as a function call to access the public field of a parent class before accessingthis
.
Property accessor getters and setters
JavaScript accessor properties allow us to access (get) and modify (set) class or object properties. The accessor properties are functions that execute on setting or getting a value. They are usually denoted using the get
and set
keywords.
Accessor Terms
Setter - A setter is a function that is used to assign a value to class properties. The
set
keyword is used to define the setter function, and it must accept exactly one parameter or value that represents the new value to assign to the property. By defining a function as a setter, it means that you can only write to the class property by assigning a new value.Getters - A getter is a function that helps us to get a class property value after it has been set. The
get
keyword is used to define the getter function. You can only read the property value of a getter function.
class Person {
constructor(){
this._name = '';
}
set name(value){
return this._name = value;
}
get name(){
return this._name;
}
}
class Student extends Person {
constructor(){
super();
this._college = '';
this._noOfCourse = '';
}
set college(value){
return this._college = value;
}
get college(){
return this._college;
}
set noOfCourse(value){
return this._noOfCourse = value;
}
get noOfCourse(){
return this._noOfCourse;
}
}
const student = new Student();
console.log(student.name) // ''
student.name = 'John';
console.log(student.name); //John
student.college = 'Standford';
console.log(student.college); // Standford
student.noOfCourse = 12;
console.log(student.noOfCourse) //12
In the Person
class, the setter and getter are defined, which help to set and get the name property. The set method has a value parameter that is used to set the name property, and the get
method which only return the set name.
In the derived class Student
, we call the parent constructor using super
, then we declare some properties that are unique to the class. We define get
and set
methods of the class properties, which help us to set and retrieve basic information such as the college
and the noOfCourse
.
We created an instance of our class student
, then we set and get the class properties using the class instance.
Note how we call our
get
method; there are no parentheses after the method name. ATypeError
is raised if parentheses are included.
Summary
JavaScript Inheritance gives us the privilege to extend the functionality of a class. The extends
keyword enables a subclass to derive properties and functions from the parent class. The super
keyword allows us to call and invoke the parent class's methods and properties, while the super()
is used within a subclass constructor as a function look-up to call the parent class constructor's public fields before accessing this
. Accessor properties, including setters and getters can be used to modify and access class properties using the set
and get
functions.
Conclusion
In JavaScript, inheritance gives developer the ability to write modular and concise JavaScript codes and helps to extend the functionality of a class by building on top of the existing class.
Top comments (0)