TypeScript类

一、前言

在面向对象编程中,类(Class)是组织代码的重要结构。TypeScript 在 JavaScript 的基础上增强了类的功能,支持类型检查、访问控制、继承、抽象等高级特性,使得代码更具结构性和可维护性。

本文将带你全面了解 TypeScript 中的类机制,包括:

✅ 类的基本定义与使用

✅ 构造函数与属性初始化

✅ 访问修饰符 public / private / protected

✅ 静态成员与只读属性

✅ 继承与多态

✅ 抽象类与接口实现

✅ 实际开发中的最佳实践

并通过完整的代码示例帮助你掌握如何用类构建复杂应用。

二、什么是类?

✅ 定义:

类是一种模板或蓝图,用于创建具有相同属性和行为的对象。它封装了数据(属性)和操作数据的方法。

⚠️ TypeScript 中的类不仅支持传统的面向对象特性,还增加了类型系统支持,使开发更安全、更高效。

三、类的基本结构

typescript 复制代码
class Person {
  name: string;

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

  sayHello(): void {
    console.log(`Hello, my name is ${this.name}`);
  }
}

const person = new Person("Alice");
person.sayHello(); // 输出:Hello, my name is Alice

四、构造函数与参数初始化

✅ 简化写法:自动赋值

typescript 复制代码
class Person {
  constructor(public name: string, private age: number) {}
}

上面的写法相当于:

typescript 复制代码
class Person {
  name: string;
  private age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

五、访问修饰符详解

修饰符 可见范围 说明
public 所有地方 默认修饰符,公开访问
private 本类内部 不可在子类或外部访问
protected 本类及子类 不可在外部访问

示例:

typescript 复制代码
class Animal {
  public name: string;
  private secret: string;
  protected id: number;

  constructor(name: string, secret: string, id: number) {
    this.name = name;
    this.secret = secret;
    this.id = id;
  }
}

class Dog extends Animal {
  showId() {
    console.log(this.id); // ✅ 子类可以访问 protected 成员
    // console.log(this.secret); ❌ 编译错误,不能访问 private 成员
  }
}

const a = new Animal("Cat", "meow", 1);
console.log(a.name); // ✅ 公共属性可以访问
// console.log(a.secret); ❌ 私有属性不可访问
// console.log(a.id); ❌ 受保护属性不可访问

六、静态属性与方法

静态成员属于类本身,而不是类的实例。

arduino 复制代码
class MathUtils {
  static PI = 3.14159;

  static calculateCircleArea(radius: number): number {
    return this.PI * radius * radius;
  }
}

console.log(MathUtils.calculateCircleArea(5)); // 输出:78.53975

七、只读属性 readonly

readonly 修饰符表示该属性只能在声明时或构造函数中被赋值。

ini 复制代码
class User {
  readonly id: number;

  constructor(id: number) {
    this.id = id;
  }
}

const user = new User(1);
// user.id = 2; ❌ 报错:无法修改只读属性

八、继承与多态

✅ 基础继承

scala 复制代码
class Animal {
  makeSound(): void {
    console.log("Some sound");
  }
}

class Dog extends Animal {
  override makeSound(): void {
    console.log("Woof!");
  }
}

const dog = new Dog();
dog.makeSound(); // 输出:Woof!

✅ 多态示例

scss 复制代码
function playSound(animal: Animal) {
  animal.makeSound();
}

playSound(new Animal()); // Some sound
playSound(new Dog());    // Woof!

九、抽象类(Abstract Class)

抽象类不能直接实例化,必须通过子类继承并实现抽象方法。

scala 复制代码
abstract class Shape {
  abstract getArea(): number;
}

class Circle extends Shape {
  constructor(private radius: number) {
    super();
  }

  getArea(): number {
    return Math.PI * this.radius * this.radius;
  }
}

const circle = new Circle(5);
console.log(circle.getArea()); // 输出:78.53981633974483

十、接口与类的实现(Implements)

类可以实现一个或多个接口,以保证其具备某些特定的行为。

typescript 复制代码
interface ILogger {
  log(message: string): void;
}

class ConsoleLogger implements ILogger {
  log(message: string): void {
    console.log(`[LOG] ${message}`);
  }
}

const logger = new ConsoleLogger();
logger.log("This is a log message."); // 输出:[LOG] This is a log message.

十一、实际开发中的常见场景

✅ 场景1:用户管理类

typescript 复制代码
class User {
  constructor(
    public id: number,
    public username: string,
    private password: string
  ) {}

  login(inputPassword: string): boolean {
    return inputPassword === this.password;
  }
}

const user = new User(1, "admin", "123456");
console.log(user.login("wrong")); // false
console.log(user.login("123456")); // true

✅ 场景2:图形库设计(抽象类 + 多态)

scala 复制代码
abstract class Shape {
  abstract getArea(): number;
}

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

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

class Circle extends Shape {
  constructor(private radius: number) {
    super();
  }

  getArea(): number {
    return Math.PI * this.radius * this.radius;
  }
}

function printArea(shape: Shape) {
  console.log(`Area: ${shape.getArea()}`);
}

printArea(new Rectangle(4, 5)); // Area: 20
printArea(new Circle(3));       // Area: 28.274333882308138

十二、注意事项与最佳实践

场景 建议
是否推荐使用 private ✅ 推荐用于隐藏敏感数据
是否允许修改 readonly 属性 ❌ 否,只能在构造函数中赋值
如何避免类膨胀? ✅ 使用组合代替继承
抽象类 vs 接口? ✅ 抽象类适合共享逻辑,接口适合定义契约
是否推荐使用 override 关键字? ✅ 推荐,增强代码可读性和安全性

十三、总结对比表:TypeScript 类常用特性一览

特性 示例 说明
构造函数 constructor() 初始化对象
访问修饰符 public, private, protected 控制访问权限
静态成员 static PI = 3.14 属于类而非实例
只读属性 readonly id: number 不可变属性
抽象类 abstract class Shape 必须被继承实现
接口实现 implements ILogger 强制实现特定方法
继承与重写 extends, override 支持多态
多态调用 函数接受父类引用 根据实际类型执行不同方法

十四、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
孤独的根号_2 分钟前
Vite背后的技术原理🚀:为什么选择Vite作为你的前端构建工具💥
前端·vue.js·vite
吹牛不交税33 分钟前
Axure RP Extension for Chrome插件安装使用
前端·chrome·axure
薛定谔的算法1 小时前
# 前端路由进化史:从白屏到丝滑体验的技术突围
前端·react.js·前端框架
拾光拾趣录2 小时前
Element Plus表格表头动态刷新难题:零闪动更新方案
前端·vue.js·element
Adolf_19932 小时前
React 中 props 的最常用用法精选+useContext
前端·javascript·react.js
前端小趴菜052 小时前
react - 根据路由生成菜单
前端·javascript·react.js
喝拿铁写前端2 小时前
`reduce` 究竟要不要用?到底什么时候才“值得”用?
前端·javascript·面试
鱼樱前端3 小时前
2025前端SSR框架之十分钟快速上手Nuxt3搭建项目
前端·vue.js
極光未晚3 小时前
React Hooks 中的时空穿梭:模拟 ComponentDidMount 的奇妙冒险
前端·react.js·源码
Codebee3 小时前
OneCode 3.0 自治UI 弹出菜单组件功能介绍
前端·人工智能·开源