CLASS 08 · 2026-03-02 · 类型与函数式

接口与子类型

本讲学习用 TypeScript 接口、泛型和枚举来定义 ADT。接口让一个抽象支持多种实现,泛型让类型参数化,枚举让有限值集合成为类型安全的 ADT。

接口

TypeScript 中的接口(interface)是一组方法签名的列表,没有方法体。它定义了「能做什么」,而不规定「怎么做」。

// 接口定义了字符串抽象的操作集合
interface MyString {
  length(): number;
  charAt(index: number): string;
  concat(other: MyString): MyString;
  substring(start: number, end: number): MyString;
}

子类型

B 是 A 的子类型(subtype),当且仅当 B 满足 A 的规格——即每个 B 都能在任何需要 A 的地方使用。

子类型关系实现了「里氏替换原则」:如果 MyArrayString 实现了 MyString 接口,那么任何接受 MyString 的代码都可以传入 MyArrayString

// 两种不同的实现,满足同一接口
class MyArrayString implements MyString {
  private readonly chars: string[];
  // 实现所有方法...
}

class MyLinkedString implements MyString {
  private readonly head: CharNode | null;
  // 实现所有方法...
}

// 使用者代码只依赖接口,不依赖具体实现
function printLength(s: MyString): void {
  console.log(s.length());
}

为什么用接口

子类化

子类化(Subclassing)是定义一个类作为另一个类的扩展。子类继承父类的实现,同时获得子类型关系。但子类化会暴露父类的实现细节,因此应谨慎使用;优先使用接口来实现多态。

泛型类型

泛型类型(Generic type)是用占位类型参数化的类型,其规格不依赖具体元素类型。

泛型让我们写出类型安全且可复用的代码:

interface List<T> {
  length(): number;
  get(index: number): T;
  append(item: T): List<T>;
}

// 实例化时指定类型参数
let numbers: List<number> = new ArrayList<number>();
let names: List<string> = new ArrayList<string>();

枚举

枚举(Enumeration)定义一个小的、有限的不可变值集合作为命名常量。

枚举适合表示固定集合的类型,例如方向、状态、星期:

enum Direction {
  NORTH, SOUTH, EAST, WEST
}

enum Color {
  RED = "#FF0000",
  GREEN = "#00FF00",
  BLUE = "#0000FF"
}

function turn(dir: Direction): void {
  switch (dir) {
    case Direction.NORTH: /* ... */ break;
    // TypeScript 会检查 switch 是否覆盖所有枚举值
  }
}

Getter 与 Setter

使用 get 关键字可以定义getter 方法,让方法调用看起来像属性访问:

class Rectangle {
  constructor(
    private readonly width: number,
    private readonly height: number
  ) {}

  get area(): number {
    return this.width * this.height;
  }
}

const r = new Rectangle(3, 4);
console.log(r.area); // 12,像访问属性一样调用方法

非面向对象语言中的 ADT

ADTs 不仅限于面向对象语言。在非 OOP 语言中,ADT 可以定义为在 opaque(不透明)数据类型上操作的函数集合——使用者只能通过函数操作数据,无法直接访问内部表示。

核心要点

接口定义操作集合,支持多种实现;优先于子类化。

子类型B 是 A 的子类型 = B 满足 A 的规格,可替换使用。

泛型与枚举泛型参数化类型,枚举定义有限值集合。