TypeScript 进阶指南(二):抽象类、接口实现与泛型类

TypeScript 进阶指南(二):抽象类、接口实现与泛型类


3. 抽象类:定义契约的模板

用户疑问:“抽象类和普通类有什么区别?为什么要用它?”

核心概念
抽象类 (abstract class) 用于定义 需要被子类实现的属性和方法模板。它本身不能被实例化,但可以包含具体实现(非抽象成员),强制子类遵循特定结构。

示例与实战

// 抽象类定义通用行为
abstract class Shape {
  abstract area(): number; // 必须被子类实现
  protected color: string = 'red'; // 非抽象属性

  printColor() { // 非抽象方法
    console.log(`Color: ${this.color}`);
  }
}

class Circle extends Shape {
  radius: number;

  constructor(radius: number) {
    super();
    this.radius = radius;
  }

  // 必须实现抽象方法
  area() {
    return Math.PI * this.radius ** 2;
  }
}

const circle = new Circle(5);
circle.printColor(); // 输出: Color: red
console.log(circle.area()); // 输出: 78.54...

使用场景

  • 需要定义公共逻辑(如 printColor)但部分行为需子类定制(如 area)。
  • 比接口更强大(可包含实现),适合有层次关系的类设计。

4. 类实现接口:多态性的另一种实现

用户疑问:“接口和抽象类都能约束类,如何选择?”

核心区别

  • 接口:仅定义类型契约,无实现,类可 实现多个接口
  • 抽象类:可包含实现,类只能 继承一个抽象类

示例与实战

// 定义多个接口
interface Loggable {
  log(message: string): void;
}

interface Serializable {
  serialize(): string;
}

// 类实现多个接口
class AppConfig implements Loggable, Serializable {
  private object = {};

  log(message: string) {
    console.log(`[LOG] ${message}`);
  }

  serialize() {
    return JSON.stringify(this.data);
  }
}

const config = new AppConfig();
config.log("Config loaded"); // 调用接口方法
console.log(config.serialize()); // 输出: {}

设计技巧

  • 用接口定义 轻量级契约(如 API 响应结构)。
  • 用抽象类定义 有共享逻辑的基类(如支付处理器基类)。

5. 泛型类:让类与类型共舞

用户疑问:“泛型在类中能解决什么问题?”

核心价值
泛型类允许 延迟指定具体类型,使类能够处理多种数据类型而不丢失类型安全。

示例与实战

// 泛型容器类
class Box<T> {
  private content: T;

  constructor(initialValue: T) {
    this.content = initialValue;
  }

  getValue(): T {
    return this.content;
  }

  setValue(newValue: T): void {
    this.content = newValue;
  }
}

// 使用不同类型初始化
const stringBox = new Box<string>("Hello");
console.log(stringBox.getValue().toUpperCase()); // 输出: HELLO

const numberBox = new Box<number>(42);
console.log(numberBox.getValue().toFixed(2)); // 输出: 42.00

进阶应用

// 泛型约束(限制类型范围)
interface HasId {
  id: number;
}

class Repository<T extends HasId> {
  private items: T[] = [];

  add(item: T) {
    this.items.push(item);
  }

  findById(id: number): T | undefined {
    return this.items.find(item => item.id === id);
  }
}

// 使用约束后的泛型类
interface User extends HasId {
  name: string;
}

const userRepo = new Repository<User>();
userRepo.add({ id: 1, name: "Alice" });
console.log(userRepo.findById(1)?.name); // 输出: Alice

总结:何时使用这些特性
特性典型场景
函数重载参数类型影响返回值类型时(如解析器)
接口继承构建类型层次结构(如车辆->汽车->电动车)
抽象类定义包含部分实现的基类(如支付处理器基类)
类实现接口需要遵循多个独立契约时(如日志+序列化)
泛型类创建类型无关的容器或工具类(如集合类)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值