TypeScript面向对象的特点

57 阅读3分钟

一、前言

随着前端项目的复杂度不断提升,良好的代码组织方式变得尤为重要。面向对象编程(Object-Oriented Programming, OOP) 是一种被广泛采用的程序设计范式,它通过“类”和“对象”的概念来构建模块化、可复用、易维护的代码结构。

TypeScript 在 JavaScript 的基础上引入了更强大的类型系统和面向对象特性,使得开发者能够以更加严谨和规范的方式编写大型应用。

本文将带你全面了解 TypeScript 中的面向对象编程特点,包括:

✅ 封装
✅ 继承
✅ 多态
✅ 抽象
✅ 接口与抽象类
✅ 访问修饰符
✅ 实际开发中的设计模式示例

并通过大量代码示例帮助你深入理解这些概念。

二、什么是面向对象编程?

✅ 定义:

面向对象编程是一种基于“对象”构建软件的方法,每个对象都是某个类的实例。类是数据(属性)和行为(方法)的封装体。

⚠️ 四大基本特征:

  1. 封装(Encapsulation)
  2. 继承(Inheritance)
  3. 多态(Polymorphism)
  4. 抽象(Abstraction)

三、TypeScript 中的类(Class)

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

四、封装(Encapsulation)

✅ 定义:

封装是指将数据和操作数据的方法绑定在一起,并对外隐藏实现细节。

✅ 示例:访问修饰符控制访问权限

修饰符可见范围
public所有地方(默认)
private仅本类内部
protected本类及子类
class BankAccount {
  private balance: number = 0;

  deposit(amount: number): void {
    if (amount > 0) {
      this.balance += amount;
    }
  }

  getBalance(): number {
    return this.balance;
  }
}

const account = new BankAccount();
account.deposit(100);
console.log(account.getBalance()); // 输出:100
// console.log(account.balance); ❌ 错误:balance 是私有属性

五、继承(Inheritance)

✅ 定义:

继承是指一个类(子类)可以继承另一个类(父类)的属性和方法,从而实现代码复用。

✅ 示例:继承与重写

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!

六、多态(Polymorphism)

✅ 定义:

多态是指同一接口在不同对象中具有不同的实现方式。

✅ 示例:多态调用

function playSound(animal: Animal) {
  animal.makeSound();
}

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

七、抽象(Abstraction)

✅ 定义:

抽象是指将复杂的实现细节隐藏起来,只暴露必要的接口供外部调用。

✅ 示例:抽象类与接口

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;
  }
}

八、接口(Interface)与抽象类(Abstract Class)

特性接口(Interface)抽象类(Abstract Class)
是否可以包含实现❌ 否(TS 3.6+ 支持默认方法)✅ 是
是否支持构造函数❌ 否✅ 是
是否支持访问修饰符✅ 是✅ 是
是否可以多重继承✅ 是(多个接口)❌ 否
是否用于共享逻辑❌ 否✅ 是

✅ 示例:接口实现

interface ILogger {
  log(message: string): void;
}

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

九、实际开发中的面向对象设计模式示例

✅ 场景1:工厂模式(Factory Pattern)

interface Product {
  use(): void;
}

class ConcreteProductA implements Product {
  use(): void {
    console.log("Using Product A");
  }
}

class ConcreteProductB implements Product {
  use(): void {
    console.log("Using Product B");
  }
}

class ProductFactory {
  static createProduct(type: string): Product {
    switch (type) {
      case "A":
        return new ConcreteProductA();
      case "B":
        return new ConcreteProductB();
      default:
        throw new Error("Unknown product type");
    }
  }
}

const product = ProductFactory.createProduct("A");
product.use(); // 输出:Using Product A

✅ 场景2:策略模式(Strategy Pattern)

interface PaymentStrategy {
  pay(amount: number): void;
}

class CreditCardPayment implements PaymentStrategy {
  pay(amount: number): void {
    console.log(`Paid $${amount} with Credit Card`);
  }
}

class PayPalPayment implements PaymentStrategy {
  pay(amount: number): void {
    console.log(`Paid $${amount} with PayPal`);
  }
}

class ShoppingCart {
  constructor(private strategy: PaymentStrategy) {}

  checkout(amount: number): void {
    this.strategy.pay(amount);
  }
}

const cart1 = new ShoppingCart(new CreditCardPayment());
cart1.checkout(100); // 输出:Paid $100 with Credit Card

const cart2 = new ShoppingCart(new PayPalPayment());
cart2.checkout(200); // 输出:Paid $200 with PayPal

十、JavaScript 原生类 vs TypeScript 类

特性JavaScript 类TypeScript 类
类型检查❌ 无✅ 强类型检查
接口❌ 不支持✅ 支持
抽象类❌ 不支持✅ 支持
访问修饰符❌ 不支持✅ 支持
默认参数值✅ 支持✅ 支持
静态方法✅ 支持✅ 支持
构造函数重载❌ 不支持✅ 支持(通过类型推断)

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

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

十二、总结对比表:TypeScript 面向对象核心特性一览

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

十三、结语

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