三小时快速上手TypeScript之抽象类
在TypeScript中,抽象类(Abstract Class)是一种特殊的类,它不能被直接实例化,而是用于定义一组相关类的通用行为和属性。抽象类可以包含抽象方法(没有实现体的方法)和具体方法(有实现体的方法)。使用抽象类可以帮助我们实现代码的复用和层次化设计。
类复习
一、定义抽象类
在TypeScript中,使用abstract
关键字来定义抽象类和抽象方法。
示例
abstract class Animal {// 抽象方法,没有实现体abstract makeSound(): void;// 具体方法,有实现体eat(): void {console.log("This animal eats food.");}
}
二、抽象类的特点
-
不能被实例化:
- 抽象类不能直接创建实例,只能被继承。
// 错误:不能直接实例化抽象类 // const animal = new Animal();
-
包含抽象方法:
- 抽象类可以包含抽象方法,抽象方法没有实现体,必须在子类中实现。
abstract class Animal {abstract makeSound(): void; }class Dog extends Animal {makeSound(): void {console.log("Bark");} }
-
包含具体方法:
- 抽象类也可以包含具体方法,具体方法有实现体,子类可以直接继承这些方法。
abstract class Animal {abstract makeSound(): void;eat(): void {console.log("This animal eats food.");} }class Dog extends Animal {makeSound(): void {console.log("Bark");} }const dog = new Dog(); dog.makeSound(); // 输出:Bark dog.eat(); // 输出:This animal eats food.
-
构造方法:
- 抽象类可以包含构造方法,但不能直接实例化,构造方法主要用于子类的初始化。
abstract class Animal {constructor(public name: string) {}abstract makeSound(): void;eat(): void {console.log(`${this.name} eats food.`);} }class Dog extends Animal {constructor(name: string) {super(name); // 调用父类的构造方法}makeSound(): void {console.log(`${this.name} says Bark`);} }const dog = new Dog("Rex"); dog.makeSound(); // 输出:Rex says Bark dog.eat(); // 输出:Rex eats food.
三、抽象类的使用场景
-
定义通用行为:
- 抽象类可以定义一组相关类的通用行为和属性,减少重复代码。
abstract class Vehicle {abstract start(): void;stop(): void {console.log("Vehicle stopped.");} }class Car extends Vehicle {start(): void {console.log("Car started.");} }const car = new Car(); car.start(); // 输出:Car started. car.stop(); // 输出:Vehicle stopped.
-
强制子类实现某些方法:
- 抽象类中的抽象方法强制子类实现这些方法,确保子类具有某些特定的行为。
abstract class Shape {abstract area(): number; }class Circle extends Shape {constructor(private radius: number) {super();}area(): number {return Math.PI * this.radius * this.radius;} }const circle = new Circle(5); console.log(circle.area()); // 输出:78.53981633974483
四、与接口的区别
-
实现方式:
- 抽象类使用
extends
关键字继承,接口使用implements
关键字实现。
abstract class Animal {abstract makeSound(): void; }class Dog extends Animal {makeSound(): void {console.log("Bark");} }interface Animal {makeSound(): void; }class Dog implements Animal {makeSound(): void {console.log("Bark");} }
- 抽象类使用
-
方法实现:
- 抽象类可以包含具体方法,接口不能包含具体方法(TypeScript 3.8之前)。
abstract class Animal {makeSound(): void {console.log("Default sound");} }interface Animal {makeSound(): void; }
-
字段:
- 抽象类可以包含字段,接口不能包含字段。
abstract class Animal {name: string;constructor(name: string) {this.name = name;} }interface Animal {name: string; }
-
多继承:
- 一个类只能继承一个抽象类,但可以实现多个接口。
class Dog extends Animal implements Swimmable {// ... }
五、总结
- 抽象类:
- 用于定义一组相关类的通用行为和属性。
- 可以包含抽象方法和具体方法。
- 不能被直接实例化,必须被继承。
- 支持单继承。
- 接口:
- 用于定义一组行为规范。
- 只能包含抽象方法(TypeScript 3.8之前)。
- 可以被多个类实现。
- 支持多实现。
在TypeScript中,抽象类和接口是两种非常重要的工具,它们在设计模式和代码结构中扮演着关键角色。选择使用抽象类还是接口,取决于具体的需求和设计目标。