TypeScript - 继承
你好,未来的程序员们!今天,我们将踏上一段激动人心的旅程,探索TypeScript继承的世界。作为你友好邻里的计算机老师,我在这里引导你了解这个迷人的主题。所以,背上你的虚拟背包,让我们一起潜水吧!
什么是继承?
在我们开始之前,让我们先了解继承实际上意味着什么。想象你正在创建一个家谱树。每一代都会从他们的父母那里继承某些特征。在编程中,继承的工作原理也是类似的。它允许一个新的类基于一个已存在的类,继承它的属性和方法。酷吧?
单类继承
让我们从最简单的继承形式开始:单类继承。这就是一个类(子类)从另一个类(父类)继承。
基本示例
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound(): void {
console.log("一些通用的动物声音");
}
}
class Dog extends Animal {
breed: string;
constructor(name: string, breed: string) {
super(name);
this.breed = breed;
}
makeSound(): void {
console.log("汪!汪!");
}
}
let myDog = new Dog("Buddy", "金毛寻回犬");
console.log(myDog.name); // 输出: Buddy
console.log(myDog.breed); // 输出: 金毛寻回犬
myDog.makeSound(); // 输出: 汪!汪!
在这个例子中,Dog
从 Animal
继承。extends
关键字用于创建一个其他类的子类。
解释
- 我们定义了一个基类
Animal
,它有一个name
属性和一个makeSound
方法。 - 然后我们创建了一个
Dog
类,它扩展了Animal
。 -
Dog
类有它自己的breed
属性。 - 我们在
Dog
构造函数中使用super
关键字来调用Animal
构造函数。 - 我们在
Dog
类中覆盖了makeSound
方法。
super 关键字
你可能在之前的例子中注意到了 super
关键字。让我们更深入地了解它的作用。
带有 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()); // 输出: Toyota Corolla with 4 doors
解释
-
super
关键字在Car
构造函数中用于调用Vehicle
构造函数。 - 在
Car
类的getInfo
方法中,我们使用super.getInfo()
来调用父类的getInfo
方法。
super
关键字允许我们访问并调用对象父类上的函数。
方法覆盖
方法覆盖发生在子类提供了一个它已经在父类中定义的方法的具体实现时。我们实际上在之前的例子中已经看到了这种情况!
方法覆盖的另一个示例
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()); // 输出: 78.53981633974483
let myRectangle = new Rectangle(4, 5);
console.log(myRectangle.getArea()); // 输出: 20
解释
- 我们有一个基类
Shape
,它有一个返回 0 的getArea
方法。 -
Circle
和Rectangle
类都扩展了Shape
并覆盖了getArea
方法。 -
Circle
类使用公式 πr² 计算面积。 -
Rectangle
类通过乘以宽度和高度来计算面积。
多级继承
多级继承涉及一个子类从另一个子类继承。这就像一个有多个世代的家谱树。
多级继承示例
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()); // 输出: John Doe Smith
解释
- 我们有一个
Grandparent
类,它有一个surname
属性。 -
Parent
类扩展了Grandparent
并添加了一个firstName
属性。 -
Child
类扩展了Parent
并添加了一个middleName
属性。 - 每个类都有它自己的
getFullName
方法实现。
继承方法的总结
这里是一个总结我们讨论过的关键方法和关键字的表格:
方法/关键字 | 描述 |
---|---|
extends |
用于创建一个类的子类 |
super() |
调用父类的构造函数 |
super.method() |
从父类调用一个方法 |
方法覆盖 | 在子类中为父类中已定义的方法提供新的实现 |
就是这样!我们已经覆盖了TypeScript继承的基础。记住,熟能生巧,所以不要犹豫,去尝试这些概念吧。祝你好运,未来的TypeScript法师!
Credits: Image by storyset