TypeScript - 继承

你好,未来的程序员们!今天,我们将踏上一段激动人心的旅程,探索TypeScript继承的世界。作为你友好邻里的计算机老师,我在这里引导你了解这个迷人的主题。所以,背上你的虚拟背包,让我们一起潜水吧!

TypeScript - Inheritance

什么是继承?

在我们开始之前,让我们先了解继承实际上意味着什么。想象你正在创建一个家谱树。每一代都会从他们的父母那里继承某些特征。在编程中,继承的工作原理也是类似的。它允许一个新的类基于一个已存在的类,继承它的属性和方法。酷吧?

单类继承

让我们从最简单的继承形式开始:单类继承。这就是一个类(子类)从另一个类(父类)继承。

基本示例

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();        // 输出: 汪!汪!

在这个例子中,DogAnimal 继承。extends 关键字用于创建一个其他类的子类。

解释

  1. 我们定义了一个基类 Animal,它有一个 name 属性和一个 makeSound 方法。
  2. 然后我们创建了一个 Dog 类,它扩展了 Animal
  3. Dog 类有它自己的 breed 属性。
  4. 我们在 Dog 构造函数中使用 super 关键字来调用 Animal 构造函数。
  5. 我们在 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

解释

  1. super 关键字在 Car 构造函数中用于调用 Vehicle 构造函数。
  2. 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

解释

  1. 我们有一个基类 Shape,它有一个返回 0 的 getArea 方法。
  2. CircleRectangle 类都扩展了 Shape 并覆盖了 getArea 方法。
  3. Circle 类使用公式 πr² 计算面积。
  4. 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

解释

  1. 我们有一个 Grandparent 类,它有一个 surname 属性。
  2. Parent 类扩展了 Grandparent 并添加了一个 firstName 属性。
  3. Child 类扩展了 Parent 并添加了一个 middleName 属性。
  4. 每个类都有它自己的 getFullName 方法实现。

继承方法的总结

这里是一个总结我们讨论过的关键方法和关键字的表格:

方法/关键字 描述
extends 用于创建一个类的子类
super() 调用父类的构造函数
super.method() 从父类调用一个方法
方法覆盖 在子类中为父类中已定义的方法提供新的实现

就是这样!我们已经覆盖了TypeScript继承的基础。记住,熟能生巧,所以不要犹豫,去尝试这些概念吧。祝你好运,未来的TypeScript法师!

Credits: Image by storyset