抽象类是面向对象编程中的基石,TypeScript 通过强大的类型系统让这一概念在前端开发中焕发出新的活力。
什么是 TypeScript 抽象类?
抽象类(Abstract Class)是一种不能被实例化的特殊类,它主要用于定义其他类的基类。在 TypeScript 中,抽象类使用 abstract 关键字声明,它可以包含抽象方法和具体方法的实现。
abstract class Animal {
// 抽象属性
abstract readonly species: string;
// 具体属性
protected age: number = 0;
// 抽象方法 - 必须在子类中实现
abstract makeSound(): void;
// 具体方法 - 可以直接使用
growUp(): void {
this.age++;
console.log(`${this.species} 现在 ${this.age} 岁了`);
}
// 受保护的方法
protected getAge(): number {
return this.age;
}
}抽象方法与具体方法的核心区别
抽象方法(Abstract Methods)
- 使用
abstract关键字声明 - 没有方法体(实现)
- 必须在派生类中实现
- 强制子类遵循特定的接口契约
abstract class DatabaseConnection {
// 抽象方法:连接数据库
abstract connect(): Promise<void>;
// 抽象方法:断开连接
abstract disconnect(): Promise<void>;
// 具体方法:获取连接状态
isConnected(): boolean {
return this.connectionState === 'connected';
}
protected connectionState: 'connected' | 'disconnected' = 'disconnected';
}具体方法(Concrete Methods)
- 有完整的实现体
- 可以直接被继承和使用
- 提供通用的功能实现
- 子类可以选择重写(override)
继承抽象类的实现方式
让我们通过一个实际的数据处理场景来展示如何正确继承抽象类:
// 定义数据处理抽象类
abstract class DataProcessor<T> {
protected data: T[] = [];
// 抽象方法:验证数据格式
abstract validate(item: T): boolean;
// 抽象方法:转换数据格式
abstract transform(item: T): any;
// 具体方法:处理数据流
async process(data: T[]): Promise<any[]> {
const results: any[] = [];
for (const item of data) {
if (this.validate(item)) {
try {
const transformed = this.transform(item);
results.push(transformed);
this.logSuccess(item);
} catch (error) {
this.logError(item, error);
}
}
}
return results;
}
// 具体方法:记录成功日志
protected logSuccess(item: T): void {
console.log(`✅ 成功处理数据:`, item);
}
// 具体方法:记录错误日志
protected logError(item: T, error: any): void {
console.error(`❌ 处理数据失败:`, item, error);
}
}
// 实现用户数据处理类
class UserDataProcessor extends DataProcessor<User> {
// 必须实现抽象方法:验证用户数据
validate(item: User): boolean {
return !!(item.id && item.name && item.email);
}
// 必须实现抽象方法:转换用户数据
transform(item: User): ProcessedUser {
return {
userId: item.id,
displayName: item.name.trim(),
emailAddress: item.email.toLowerCase(),
processedAt: new Date().toISOString()
};
}
}
// 使用示例
interface User {
id: number;
name: string;
email: string;
}
interface ProcessedUser {
userId: number;
displayName: string;
emailAddress: string;
processedAt: string;
}
const processor = new UserDataProcessor();
const users: User[] = [
{ id: 1, name: " 张三 ", email: "ZHANG@example.com" },
{ id: 2, name: "李四", email: "li@example.com" }
];
processor.process(users).then(results => {
console.log("处理结果:", results);
});实际项目应用场景
1. 插件系统架构
// 定义插件抽象类
abstract class Plugin {
readonly name: string;
readonly version: string;
constructor(name: string, version: string) {
this.name = name;
this.version = version;
}
// 抽象方法:初始化插件
abstract initialize(): Promise<void>;
// 抽象方法:执行插件功能
abstract execute(context: PluginContext): Promise<any>;
// 抽象方法:清理资源
abstract cleanup(): Promise<void>;
// 具体方法:获取插件信息
getInfo(): PluginInfo {
return {
name: this.name,
version: this.version,
status: this.getStatus()
};
}
// 受保护的方法:获取状态
protected abstract getStatus(): PluginStatus;
}
// 实现具体的日志插件
class LoggerPlugin extends Plugin {
private logger: Logger;
constructor() {
super("LoggerPlugin", "1.0.0");
this.logger = new Logger();
}
async initialize(): Promise<void> {
await this.logger.initialize();
console.log(`${this.name} 初始化完成`);
}
async execute(context: PluginContext): Promise<any> {
this.logger.log(`执行插件: ${context.operation}`);
return { success: true, timestamp: Date.now() };
}
async cleanup(): Promise<void> {
await this.logger.close();
}
protected getStatus(): PluginStatus {
return this.logger.isReady() ? 'ready' : 'error';
}
}2. 表单验证框架
// 抽象验证器
abstract class Validator<T = any> {
protected errorMessage: string = '';
// 抽象方法:执行验证
abstract validate(value: T): boolean;
// 具体方法:获取错误信息
getErrorMessage(): string {
return this.errorMessage;
}
// 具体方法:链式验证
and(validator: Validator<T>): Validator<T> {
return new AndValidator(this, validator);
}
// 具体方法:或验证
or(validator: Validator<T>): Validator<T> {
return new OrValidator(this, validator);
}
}
// 具体验证器实现
class RequiredValidator extends Validator<string> {
validate(value: string): boolean {
const isValid = value !== null && value !== undefined && value.trim() !== '';
if (!isValid) {
this.errorMessage = '此字段为必填项';
}
return isValid;
}
}
class EmailValidator extends Validator<string> {
validate(value: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const isValid = emailRegex.test(value);
if (!isValid) {
this.errorMessage = '请输入有效的邮箱地址';
}
return isValid;
}
}