TypeScript 类(超详细)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

在现代 Web 开发中,TypeScript 因其静态类型系统和面向对象编程(OOP)的支持,逐渐成为开发者青睐的工具。其中,“TypeScript 类”是面向对象编程的核心概念之一,它通过封装、继承和多态等特性,帮助开发者构建结构清晰、可维护的代码。无论是编程初学者还是中级开发者,掌握 TypeScript 类的使用方法和设计模式,都能显著提升代码的健壮性和扩展性。本文将从基础到进阶,通过实际案例和代码示例,深入解析 TypeScript 类的特性与应用场景。


一、TypeScript 类的基础语法

1.1 类的定义与实例化

在 TypeScript 中,使用 class 关键字定义一个类,类名通常遵循大驼峰命名法(PascalCase)。类通过 new 关键字实例化,生成对象实例。

class Car {  
  // 属性定义  
  brand: string;  
  model: string;  
  constructor(brand: string, model: string) {  
    this.brand = brand;  
    this.model = model;  
  }  
}  

// 实例化  
const myCar = new Car("Toyota", "Corolla");  
console.log(myCar.brand); // 输出 "Toyota"  

形象比喻:类就像一张图纸,描述了“汽车”应有的属性和行为;而实例(如 myCar)则是根据图纸建造的具体汽车。

1.2 构造函数与属性初始化

构造函数(constructor)是类的特殊方法,用于初始化实例属性。在 TypeScript 中,可以通过参数属性语法简化代码:

class Car {  
  // 参数属性语法:直接在构造函数参数前加访问修饰符  
  constructor(public brand: string, public model: string) {}  
}  

const anotherCar = new Car("Tesla", "Model S");  
console.log(anotherCar.model); // 输出 "Model S"  

关键点:使用 public 修饰的参数会自动成为类的属性,并省略显式定义属性的步骤。


二、类的成员类型与访问控制

2.1 成员类型:属性与方法

类包含两种主要成员:属性(存储数据)和 方法(执行操作)。

class Calculator {  
  // 属性  
  private result: number = 0;  

  // 方法  
  add(num: number): void {  
    this.result += num;  
  }  

  getResult(): number {  
    return this.result;  
  }  
}  

const calc = new Calculator();  
calc.add(5);  
console.log(calc.getResult()); // 输出 5  

2.2 访问修饰符:控制成员的可见性

TypeScript 提供了 publicprivateprotected 三种访问修饰符,用于限制类成员的访问范围:

修饰符作用范围
public默认值,可在任何地方访问
private仅在类内部访问,子类不可继承
protected在类和子类中可访问,外部不可访问

形象比喻private 像是房间的锁,只有屋内的人能打开;protected 则允许家人(子类)使用钥匙,但外人仍无法进入。


三、继承与多态:构建类的层次结构

3.1 继承:复用与扩展

通过 extends 关键字,子类可以继承父类的属性和方法,并在此基础上扩展新功能。

class Animal {  
  constructor(public name: string) {}  

  makeSound(): void {  
    console.log("Some generic sound");  
  }  
}  

class Dog extends Animal {  
  // 覆盖父类方法(多态)  
  makeSound(): void {  
    console.log("Bark!");  
  }  

  // 子类新增方法  
  fetch(): void {  
    console.log(`${this.name} is fetching the ball!`);  
  }  
}  

const myDog = new Dog("Buddy");  
myDog.makeSound(); // 输出 "Bark!"  
myDog.fetch();     // 输出 "Buddy is fetching the ball!"  

3.2 覆盖方法与调用父类方法

子类可以通过 super 关键字调用父类方法,实现对父类行为的扩展:

class Cat extends Animal {  
  makeSound(): void {  
    super.makeSound(); // 输出父类的 "Some generic sound"  
    console.log("Meow!"); // 添加子类行为  
  }  
}  

四、静态成员与抽象类

4.1 静态成员:类级别的共享属性

静态成员(用 static 修饰)属于类本身,而非实例,适用于需要全局共享的场景:

class MathUtils {  
  static PI = 3.14159;  

  static calculateArea(radius: number): number {  
    return MathUtils.PI * radius ** 2;  
  }  
}  

console.log(MathUtils.calculateArea(2)); // 输出约 12.5664  

4.2 抽象类:定义模板与约束

抽象类(abstract class)不能被实例化,主要用于为子类定义统一的接口和基础逻辑:

abstract class Shape {  
  abstract getArea(): number; // 必须在子类中实现  

  printArea(): void {  
    console.log(`Area: ${this.getArea()}`);  
  }  
}  

class Rectangle extends Shape {  
  constructor(public width: number, public height: number) {  
    super();  
  }  

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

const rect = new Rectangle(3, 4);  
rect.printArea(); // 输出 "Area: 12"  

五、泛型类:增强类型灵活性

通过泛型(<T>),类可以支持多种数据类型的通用逻辑:

class Stack<T> {  
  private items: T[] = [];  

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

  pop(): T | undefined {  
    return this.items.pop();  
  }  
}  

const numberStack = new Stack<number>();  
numberStack.push(10);  
console.log(numberStack.pop()); // 输出 10  

const stringStack = new Stack<string>();  
stringStack.push("Hello");  
console.log(stringStack.pop()); // 输出 "Hello"  

六、高级特性:装饰器与私有字段

6.1 装饰器:元编程的利器

装饰器(Decorator)通过 @ 符号,为类或方法添加额外功能。例如,日志装饰器:

function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {  
  const originalMethod = descriptor.value;  
  descriptor.value = function (...args: any[]) {  
    console.log(`Calling ${propertyKey} with ${args}`);  
    return originalMethod.apply(this, args);  
  };  
  return descriptor;  
}  

class Logger {  
  @logMethod  
  logMessage(message: string): void {  
    console.log(message);  
  }  
}  

const logger = new Logger();  
logger.logMessage("Hello TypeScript!");  
// 输出:  
// "Calling logMessage with ["Hello TypeScript!"]"  
// "Hello TypeScript!"  

6.2 私有字段:#符号的简洁语法

TypeScript 4.0 引入了私有字段语法(#),简化了私有属性的定义:

class User {  
  #name: string;  

  constructor(name: string) {  
    this.#name = name;  
  }  

  getName(): string {  
    return this.#name;  
  }  
}  

const user = new User("Alice");  
console.log(user.getName()); // 输出 "Alice"  
// console.log(user.#name); // 报错:私有字段无法在外部访问  

结论

TypeScript 类是构建可维护、可扩展代码的核心工具。从基础语法到继承、泛型、装饰器等高级特性,它提供了丰富的面向对象编程能力。通过合理使用访问修饰符、静态成员和抽象类,开发者可以设计出层次清晰、复用性强的代码结构。对于编程初学者,建议从简单类的定义和继承开始实践;中级开发者则可探索泛型和装饰器,进一步提升代码的灵活性与健壮性。掌握 TypeScript 类的精髓,将为你的开发之路奠定坚实的基础。


通过本文的讲解,希望读者能对 TypeScript 类有全面的理解,并在实际项目中灵活运用这些概念。记住,实践是掌握知识的最佳途径——动手编写代码,逐步构建属于你的类体系吧!

最新发布