Lesson 5

Inheritance: Unlocking Code Reusability in JavaScript

Introduction to Inheritance

Greetings, coder! Our voyage into Object-Oriented Programming (OOP) continues. Today, we will cover Inheritance, which can make our code more efficient and tidy.

Inheritance: First Example

Just as children inherit traits from their parents, child classes in programming inherit behaviors and properties from parent classes.

Below is a practical example displaying a child class inheriting from a parent class:

1// Parent class 2class Parent { 3 constructor(name) { 4 this.name = name; // name property 5 } 6 7 greet() { 8 console.log(`Hello, my name is ${this.name}`); // greet method 9 } 10} 11 12// 'Child' class extending 'Parent' 13class Child extends Parent { 14 constructor(name, age) { 15 super(name); // call to parent constructor of `Parent` 16 this.age = age; // age property 17 } 18 19 info() { 20 console.log(`I am ${this.age} years old.`); // info method 21 } 22} 23 24const child = new Child('Alice', 10); 25child.greet(); // prints: Hello, my name is Alice 26child.info(); // prints: I am 10 years old.

In this example, Child inherits from Parent, so it shares the greet() method, making our code smarter!

Understanding the 'extends' Keyword

To implement inheritance, we introduce a keyword: 'extends'. This powerful keyword allows a new class to inherit properties and methods from an existing class. Let's say, a 'child' class 'extends' from the 'parent' class.

Let's see how a car can extend a vehicle. Both are entities with the potential for motion, but a car offers additional specific features — such as wheels.

1// Vehicle class 2class Vehicle { 3 constructor(name, speed) { 4 this.name = name; // name property 5 this.speed = speed; // speed property 6 } 7 move() { 8 console.log(`${this.name} moves at ${this.speed} mph.`); // move method 9 } 10} 11 12// 'Car' class extending 'Vehicle' 13class Car extends Vehicle { 14 constructor(name, speed, wheels) { 15 super(name, speed); // call to parent constructor 16 this.wheels = wheels; // new wheels property 17 } 18 specs() { 19 console.log(`I am a ${this.name} and I have ${this.wheels} wheels.`); // specs method 20 } 21} 22 23const myCar = new Car('Toyota', 120, 4); 24myCar.move(); // prints: Toyota moves at 120 mph 25myCar.specs(); // prints: I am a Toyota and I have 4 wheels.

In this code, the Car class extends from the Vehicle class, sharing the move() method.

Learning about the 'super' Keyword

The super keyword calls the parent class's constructor and provides access to its properties and methods. Let's consider a real-life instance of an apple inheriting from a fruit.

1class Fruit { 2 constructor(name) { 3 this.name = name; // name property 4 console.log(`Calling Fruit constructor with name=${name}`); 5 } 6 7 printName() { 8 console.log(`Fruit name: ${this.name}`); 9 } 10} 11 12class Apple extends Fruit { 13 constructor(name, color) { 14 super(name); // call to parent class constructor 15 this.color = color; // color property 16 console.log(`Calling Apple constructor with name=${name}, color=${color}`); 17 } 18 19 printColor() { 20 console.log(`Color of ${this.name} is ${this.color}`); 21 } 22} 23 24let apple = new Apple('Apple', 'Red'); 25// Prints: 26// Calling Fruit constructor with name=Apple 27// Calling Apple constructor name=Apple, color=Red 28 29apple.printName(); // Prints: Fruit name: Apple 30apple.printColor(); // Prints: Color of Apple is Red

Here, in the Apple class, super calls the constructor of the Fruit class to inherit the name property. If the child's Apple class does not have any constructor, JavaScript will automatically call the parent's constructor when creating an instance of the Apple class.

Redefinition and Override of Methods in Inheritance

During inheritance, there may be instances where a child class needs a different behavior for a method than what the parent class provides. That's where method redefinition, also known as method overriding, comes into play.

Method overriding allows a child class to provide a different implementation of a method that is already defined by its parent class. By using the same method name, with the same parameters in the child class, the parent class's method will be overridden.

Here's a practical example:

1class Parent { 2 greet() { 3 console.log('Hello from Parent'); 4 } 5} 6 7class Child extends Parent { 8 // Method override 9 greet() { 10 console.log('Hello from Child'); 11 } 12} 13 14const child = new Child(); 15child.greet(); // prints: Hello from Child

In the code above, the Child class overrides the greet() method of Parent. When we call the greet() method on an instance of Child, the message from the Child class is printed, not from the Parent class.

It's a Flexibility feature of OOP that allows us to make our classes more specific and fitting for their intended use. Always handle with care — respect the intended use of inherited methods and make sure your updated method suits your class's needs!

Lesson Summary and Practice

Excellent work! Today, we've mastered inheritance in JavaScript, noted how properties and methods pass from the parent to the child class via extends, and understood how super connects a child class with its parent class.

Up next are engaging practice exercises where you'll implement classes related to real-world scenarios. Remember, practice makes perfect! Stay motivated, and good luck with your coding journey!

Enjoy this lesson? Now it's time to practice with Cosmo!

Practice is how you turn knowledge into actual skills.