TypeScript - 繼承
Hello, future programmers! Today, we're going to embark on an exciting journey into the world of TypeScript inheritance. As your friendly neighborhood computer teacher, I'm here to guide you through this fascinating topic. So, grab your virtual backpacks, and let's dive in!
What is Inheritance?
Before we start, let's understand what inheritance actually means. Imagine you're creating a family tree. Each new generation inherits certain traits from their parents. In programming, inheritance works similarly. It allows a new class to be based on an existing class, inheriting its properties and methods. Cool, right?
Single Class Inheritance
Let's start with the simplest form of inheritance: single class inheritance. This is when one class (child class) inherits from another class (parent class).
Basic Example
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound(): void {
console.log("Some generic animal sound");
}
}
class Dog extends Animal {
breed: string;
constructor(name: string, breed: string) {
super(name);
this.breed = breed;
}
makeSound(): void {
console.log("Woof! Woof!");
}
}
let myDog = new Dog("Buddy", "Golden Retriever");
console.log(myDog.name); // Output: Buddy
console.log(myDog.breed); // Output: Golden Retriever
myDog.makeSound(); // Output: Woof! Woof!
In this example, Dog
is inheriting from Animal
. The extends
keyword is used to create a class that is a child of another class.
Explanation
- We define a base
Animal
class with aname
property and amakeSound
method. - We then create a
Dog
class that extendsAnimal
. - The
Dog
class has its ownbreed
property. - We use the
super
keyword in theDog
constructor to call theAnimal
constructor. - We override the
makeSound
method in theDog
class.
Super Keyword
You might have noticed the super
keyword in our previous example. Let's dive deeper into what it does.
Example with Super
class Vehicle {
make: string;
model: string;
constructor(make: string, model: string) {
this.make = make;
this.model = model;
}
getInfo(): string {
return `${this.make} ${this.model}`;
}
}
class Car extends Vehicle {
numDoors: number;
constructor(make: string, model: string, numDoors: number) {
super(make, model);
this.numDoors = numDoors;
}
getInfo(): string {
return `${super.getInfo()} with ${this.numDoors} doors`;
}
}
let myCar = new Car("Toyota", "Corolla", 4);
console.log(myCar.getInfo()); // Output: Toyota Corolla with 4 doors
Explanation
- The
super
keyword is used in theCar
constructor to call theVehicle
constructor. - In the
getInfo
method ofCar
, we usesuper.getInfo()
to call thegetInfo
method of the parent class.
The super
keyword allows us to access and call functions on an object's parent.
Method Overriding
Method overriding occurs when a child class provides a specific implementation of a method that is already defined in its parent class. We've actually seen this in both our previous examples!
Another Example of Method Overriding
class Shape {
getArea(): number {
return 0;
}
}
class Circle extends Shape {
radius: number;
constructor(radius: number) {
super();
this.radius = radius;
}
getArea(): number {
return Math.PI * this.radius * this.radius;
}
}
class Rectangle extends Shape {
width: number;
height: number;
constructor(width: number, height: number) {
super();
this.width = width;
this.height = height;
}
getArea(): number {
return this.width * this.height;
}
}
let myCircle = new Circle(5);
console.log(myCircle.getArea()); // Output: 78.53981633974483
let myRectangle = new Rectangle(4, 5);
console.log(myRectangle.getArea()); // Output: 20
Explanation
- We have a base
Shape
class with agetArea
method that returns 0. - Both
Circle
andRectangle
classes extendShape
and override thegetArea
method with their own implementations. - The
Circle
class calculates the area using the formula πr². - The
Rectangle
class calculates the area by multiplying width and height.
Multilevel Inheritance
Multilevel inheritance involves a child class inheriting from another child class. It's like a family tree with multiple generations.
Multilevel Inheritance Example
class Grandparent {
surname: string;
constructor(surname: string) {
this.surname = surname;
}
getSurname(): string {
return this.surname;
}
}
class Parent extends Grandparent {
firstName: string;
constructor(firstName: string, surname: string) {
super(surname);
this.firstName = firstName;
}
getFullName(): string {
return `${this.firstName} ${this.getSurname()}`;
}
}
class Child extends Parent {
middleName: string;
constructor(firstName: string, middleName: string, surname: string) {
super(firstName, surname);
this.middleName = middleName;
}
getFullName(): string {
return `${this.firstName} ${this.middleName} ${this.getSurname()}`;
}
}
let myChild = new Child("John", "Doe", "Smith");
console.log(myChild.getFullName()); // Output: John Doe Smith
Explanation
- We have a
Grandparent
class with asurname
property. - The
Parent
class extendsGrandparent
and adds afirstName
property. - The
Child
class extendsParent
and adds amiddleName
property. - Each class has its own implementation of
getFullName
method.
Summary of Inheritance Methods
Here's a table summarizing the key methods and keywords we've discussed:
Method/Keyword | Description |
---|---|
extends |
Used to create a class as a child of another class |
super() |
Calls the constructor of the parent class |
super.method() |
Calls a method from the parent class |
Method Overriding | Providing a new implementation for a method in a child class |
And there you have it! We've covered the basics of inheritance in TypeScript. Remember, practice makes perfect, so don't hesitate to experiment with these concepts. Happy coding, future TypeScript wizards!
Credits: Image by storyset