当前位置:  首页>> 技术小册>> TypeScript开发实战

第十章 类(1):继承和成员修饰符

在TypeScript的世界中,类(Class)是面向对象编程(OOP)的核心概念之一,它允许我们创建具有特定属性和方法的对象模板。本章将深入探讨TypeScript中的类继承机制以及成员修饰符的使用,这些特性对于构建可复用、可扩展且易于维护的代码库至关重要。

10.1 类的继承基础

在面向对象编程中,继承是一种允许我们根据一个已存在的类(称为基类或父类)来创建新类(称为派生类或子类)的机制。子类继承父类的属性和方法,并可以添加新的属性或重写已有的方法,实现功能的扩展或修改。

10.1.1 基本的继承语法

TypeScript中的继承通过extends关键字实现。以下是一个简单的继承示例:

  1. class Animal {
  2. name: string;
  3. constructor(name: string) {
  4. this.name = name;
  5. }
  6. move(): void {
  7. console.log(`${this.name} moves.`);
  8. }
  9. }
  10. class Dog extends Animal {
  11. bark(): void {
  12. console.log(`${this.name} barks.`);
  13. }
  14. }
  15. const myDog = new Dog('Buddy');
  16. myDog.move(); // 输出: Buddy moves.
  17. myDog.bark(); // 输出: Buddy barks.

在上面的例子中,Dog类通过extends关键字继承了Animal类。因此,Dog类的实例myDog不仅拥有Dog类自身定义的bark方法,还继承了Animal类的name属性和move方法。

10.1.2 构造函数和继承

在子类中,如果你定义了自己的构造函数,则需要通过super()调用父类的构造函数,以确保父类被正确初始化。super()可以传递参数给父类的构造函数:

  1. class Dog extends Animal {
  2. constructor(name: string) {
  3. super(name); // 调用父类的构造函数
  4. // 其他初始化代码
  5. }
  6. bark(): void {
  7. console.log(`${this.name} barks.`);
  8. }
  9. }

10.1.3 访问器属性

在TypeScript中,我们还可以使用getter和setter来定义访问器属性,这些属性允许我们对类的私有成员进行封装和控制。访问器属性在继承中尤其有用,因为它们允许子类提供额外的逻辑来处理父类属性的访问:

  1. class Person {
  2. private _age: number;
  3. constructor(age: number) {
  4. this._age = age;
  5. }
  6. get age(): number {
  7. return this._age;
  8. }
  9. set age(value: number) {
  10. if (value < 0) {
  11. throw new Error("Age cannot be negative.");
  12. }
  13. this._age = value;
  14. }
  15. }
  16. class Employee extends Person {
  17. set age(value: number) {
  18. if (value > 65) {
  19. console.log('Employee retirement age set to 65.');
  20. super.age = 65;
  21. } else {
  22. super.age = value;
  23. }
  24. }
  25. }
  26. const emp = new Employee(67);
  27. emp.age = 67; // 输出: Employee retirement age set to 65.
  28. console.log(emp.age); // 输出: 65

10.2 成员修饰符

在TypeScript中,成员修饰符用于定义类成员的访问级别。主要有三种访问修饰符:publicprotected、和private

10.2.1 public

public修饰符表示该成员是公开的,可以在类的任何地方、子类以及类的实例中被访问。默认情况下,如果不指定访问修饰符,成员将被视为public

10.2.2 private

private修饰符表示该成员是私有的,只能在定义它的类内部被访问,子类或类的实例都无法访问它。

  1. class Base {
  2. private secret: string = "I'm a secret!";
  3. showSecret(): void {
  4. console.log(this.secret);
  5. }
  6. }
  7. class Derived extends Base {
  8. // 以下尝试访问secret将报错
  9. // showSecretToo(): void {
  10. // console.log(this.secret); // 错误:'secret' 是私有的,只能在类 'Base' 中访问
  11. // }
  12. }

10.2.3 protected

protected修饰符表示该成员是受保护的,只能在定义它的类及其子类中访问,但无法在类的实例外部访问。

  1. class Base {
  2. protected name: string;
  3. constructor(name: string) {
  4. this.name = name;
  5. }
  6. }
  7. class Derived extends Base {
  8. sayHello(): void {
  9. console.log(`Hello, my name is ${this.name}.`);
  10. }
  11. }
  12. // 以下尝试访问name将报错
  13. // const base = new Base('Alice');
  14. // console.log(base.name); // 错误:'name' 是受保护的,只能在类 'Base' 及其子类中访问

10.3 继承中的高级话题

10.3.1 方法重写(Overriding)

在子类中,我们可以重写从父类继承的方法。这允许我们为继承的方法提供新的实现。

  1. class Animal {
  2. move(): void {
  3. console.log('Animal moves.');
  4. }
  5. }
  6. class Dog extends Animal {
  7. move(): void {
  8. console.log('Dog moves with four legs.');
  9. }
  10. }

10.3.2 super关键字

在子类中,super关键字可以用于调用父类的构造函数、方法和访问父类的属性。这在进行方法重写时特别有用,允许我们在子类中调用父类方法的原始实现。

  1. class Animal {
  2. constructor(public name: string) {}
  3. move(): void {
  4. console.log(`${this.name} moves.`);
  5. }
  6. }
  7. class Dog extends Animal {
  8. move(): void {
  9. super.move(); // 调用父类的move方法
  10. console.log(`${this.name} barks.`);
  11. }
  12. }

10.3.3 抽象类和抽象方法

TypeScript还支持抽象类和抽象方法。抽象类是一个不能被实例化的类,通常用作基类,为子类提供通用的接口。抽象方法是没有具体实现的方法,必须在子类中实现。

  1. abstract class Animal {
  2. abstract move(): void; // 抽象方法
  3. }
  4. class Dog extends Animal {
  5. move(): void {
  6. console.log('Dog moves.');
  7. }
  8. }

10.4 小结

在本章中,我们深入探讨了TypeScript中的类继承机制和成员修饰符的使用。通过继承,我们可以基于已存在的类创建新的类,实现代码的复用和扩展。而成员修饰符则帮助我们控制类成员的访问级别,增强代码的封装性和安全性。此外,我们还讨论了继承中的高级话题,如方法重写、super关键字的使用、以及抽象类和抽象方法的概念。掌握这些概念,将使你能够更加灵活地运用TypeScript的面向对象特性,编写出更加高效、可维护的代码。


该分类下的相关小册推荐: