Welcome back to our exploration of Object-Oriented Programming (OOP) in TypeScript. This unit's topic is Inheritance, a feature that can significantly enhance code reusability and efficiency.
Inheritance: First Example
Programming, especially OOP, often mirrors concepts found in the real world. Inheritance is one such trait - Child classes inherit characteristics from their Parent classes, akin to genetics in biology.
Here is a concrete TypeScript demonstration of a Child class inheriting from a Parent class:
TypeScript
// Parent classclass Parent { name: string; // name property constructor(name: string) { this.name = name; } greet(): void { console.log(`Hello, my name is ${this.name}`); // greet method }}// 'Child' class extending 'Parent'class Child extends Parent { age: number; // age property constructor(name: string, age: number) { super(name); this.age = age; } info(): void { console.log(`I am ${this.age} years old.`); // info method }}const child = new Child('Alice', 10);child.greet(); // prints: Hello, my name is Alicechild.info(); // prints: I am 10 years old.
In this instance, the Child class inherits from the Parent class, thereby sharing the greet() method. This is inheritance in action!
The 'extends' Keyword
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal
We introduce the keyword extends for implementing inheritance. It's a potent keyword that allows a new class to inherit properties and methods from an existing class. In short, a Child class extends from a Parent class.
For example, a Car extends a Vehicle. While both have the potential for movement, a Car has additional specific attributes — such as the number of wheels.
TypeScript
// Vehicle classclass Vehicle { name: string; // name property speed: number; // speed property constructor(name: string, speed: number) { this.name = name; this.speed = speed; } move(): void { console.log(`${this.name} moves at ${this.speed} mph.`); // move method }}// 'Car' class extending 'Vehicle'class Car extends Vehicle { wheels: number; // new wheels property constructor(name: string, speed: number, wheels: number) { super(name, speed); // call to parent constructor this.wheels = wheels; } specs(): void { console.log(`I am a ${this.name} and I have ${this.wheels} wheels.`); // specs method }}const myCar = new Car('Toyota', 120, 4);myCar.move(); // prints: Toyota moves at 120 mphmyCar.specs(); // prints: I am a Toyota and I have 4 wheels.
In this demonstration, the Car class extends the Vehicle class, adopting the move() method.
Discovering the 'super' Keyword
Redefining and Overriding Methods using Inheritance
Occasionally during inheritance, a Child class might require a different method behavior than its Parent class. This is where method redefinition, or method overriding, comes into the picture.
Method overriding enables a Child class to offer a different implementation of methods that are already defined in its Parent class. Using the same method name and parameters in the Child class, the Parent class's method can be overridden.
Here's a practical example:
class Parent { greet(): void { console.log('Hello from Parent'); }}class Child extends Parent { // Method override greet(): void { console.log('Hello from Child'); }}const child = new Child();child.greet(); // prints: Hello from Child
In this script, the Child class overrides the Parent class's greet(). When we invoke greet() on a Child instance, the Child class message is printed, not the Parent's.
It's OOP's flexibility allowing us to tailor classes to meet their intended purpose. Handle it with care — respect the intended use of inherited methods and ensure your updated method is suitable for your class's needs!
Lesson Summary and Practice
Great work! Today, we've covered and understood inheritance in TypeScript, explored how properties and methods traverse from a parent class to a child class via extends, and identified how super initiates a connection between a child class and its parent class.
The next step is effective practice sessions, where you'll create classes related to real-world scenarios. And remember, practice is the key to mastery! Stay motivated, and continue building your coding prowess!
The factor that unites the parent and child class is the super keyword. It calls the constructor of the parent class to enable the inheritance of its properties and methods. A real-world parallel would be an apple, a variety of fruit, inheriting from its parent category Fruit.
TypeScript
class Fruit { name: string; // name property constructor(name: string) { this.name = name; console.log(`Fruit's constructor called with name=${name}`); } printName(): void { console.log(`Fruit's name: ${this.name}`); }}class Apple extends Fruit { color: string; // color property constructor(name: string, color: string) { super(name); // calling parent class constructor this.color = color; console.log(`Apple's constructor called with name=${name}, color=${color}`); } printColor(): void { console.log(`Color of ${this.name} is ${this.color}`); }}let apple = new Apple('Apple', 'Red');// Prints:// Fruit's constructor called with name=Apple// Apple's constructor called with name=Apple, color=Redapple.printName(); // Prints: Fruit's name: Appleapple.printColor(); // Prints: Color of Apple is Red
In the Apple class above, super calls the constructor of the Fruit class, inheriting the name property and the printName() method. If the Apple class didn't have any constructor, TypeScript would automatically call the parent's constructor when creating an instance of the Apple class.
TypeScript
class Parent { greet(): void { console.log('Hello from Parent'); }}class Child extends Parent { // Method override greet(): void { console.log('Hello from Child'); }}const child = new Child();child.greet(); // prints: Hello from Child