TypeScript 类(Class)完全指南
目录
基本概念
类的定义
class Person {
// 属性声明
name: string;
age: number;
// 构造函数
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// 方法
sayHello(): void {
console.log(`Hello, I'm ${this.name}`);
}
}
// 使用类
const person = new Person("John", 30);
person.sayHello(); // 输出: Hello, I'm John
属性简写
// 使用访问修饰符可以自动创建并初始化属性
class Person {
constructor(
public name: string,
private age: number,
protected email: string
) {}
}
// 等同于
class Person {
public name: string;
private age: number;
protected email: string;
constructor(name: string, age: number, email: string) {
this.name = name;
this.age = age;
this.email = email;
}
}
类的定义解释
什么是类?
类(Class)是一个用于创建对象的模板,它封装了数据和操作数据的方法。类是面向对象编程的基础构建块。
类的组成部分:
- 构造函数(Constructor)
- 用于初始化类的新实例
- 在创建对象时自动调用
- 可以接收参数来设置初始状态
class Person {
name: string;
age: number;
// 构造函数
constructor(name: string, age: number) {
// 初始化实例属性
this.name = name;
this.age = age;
}
}
- 属性(Properties)
- 类的数据成员
- 可以是实例属性或静态属性
- 可以有访问修饰符
class Example {
// 实例属性
public name: string; // 公共属性
private age: number; // 私有属性
protected email: string; // 受保护属性
readonly id: string; // 只读属性
static count: number = 0; // 静态属性
optional?: string; // 可选属性
}
- 方法(Methods)
- 类的行为
- 可以访问和修改类的属性
- 可以是实例方法或静态方法
class Calculator {
// 实例方法
add(a: number, b: number): number {
return a + b;
}
// 静态方法
static multiply(a: number, b: number): number {
return a * b;
}
}
- 访问器(Accessors)
- getter 和 setter 方法
- 用于控制属性的访问和修改
class Person {
private _age: number = 0;
// getter
get age(): number {
return this._age;
}
// setter
set age(value: number) {
if (value >= 0 && value <= 120) {
this._age = value;
}
}
}
类的特性:
- 封装(Encapsulation)
- 将数据和方法捆绑在一起
- 通过访问修饰符控制访问权限
class BankAccount {
private balance: number = 0;
deposit(amount: number): void {
if (amount > 0) {
this.balance += amount;
}
}
getBalance(): number {
return this.balance;
}
}
- 继承(Inheritance)
- 允许类继承另一个类的特性
- 支持代码重用
class Animal {
protected name: string;
constructor(name: string) {
this.name = name;
}
}
class Dog extends Animal {
bark(): void {
console.log(`${this.name} says woof!`);
}
}
- 多态(Polymorphism)
- 允许使用父类类型引用子类对象
- 支持方法重写
class Shape {
area(): number {
return 0;
}
}
class Circle extends Shape {
constructor(private radius: number) {
super();
}
override area(): number {
return Math.PI * this.radius ** 2;
}
}
class Square extends Shape {
constructor(private side: number) {
super();
}
override area(): number {
return this.side ** 2;
}
}
// 多态使用
const shapes: Shape[] = [
new Circle(5),
new Square(4)
];
shapes.forEach(shape => {
console.log(shape.area()); // 调用各自的实现
});
类的成员
1. 实例属性
class Car {
// 实例属性
brand: string;
model: string;
year: number = 2023; // 可以设置默认值
// 可选属性
color?: string;
// 只读属性
readonly vin: string;
constructor(brand: string, model: string, vin: string) {
this.brand = brand;
this.model = model;
this.vin = vin;
}
}
2. 静态成员
class MathUtils {
// 静态属性
static PI: number = 3.14159;
// 静态方法
static square(x: number): number {
return x * x;
}
// 静态块(ES2022+)
static {
// 初始化静态成员
this.PI = Math.PI;
}
}
console.log(MathUtils.PI); // 3.14159
console.log(MathUtils.square(4)); // 16
3. 访问器
class Employee {
private _salary: number = 0;
// getter
get salary(): number {
return this._salary;
}
// setter
set salary(value: number) {
if (value >= 0) {
this._salary = value;
}
}
}
const emp = new Employee();
emp.salary = 5000; // 使用 setter
console.log(emp.salary); // 使用 getter,输出: 5000
继承
基本继承
class Animal {
constructor(protected name: string) {}
move(distance: number = 0): void {
console.log(`${this.name} moved ${distance}m.`);
}
}
class Dog extends Animal {
constructor(name: string) {
super(name); // 调用父类构造函数
}
// 重写父类方法
move(distance: number = 5): void {
console.log("Running...");
super.move(distance); // 调用父类方法
}
// 新增方法
bark(): void {
console.log("Woof! Woof!");
}
}
方法重写
class Shape {
getArea(): number {
return 0;
}
}
class Circle extends Shape {
constructor(private radius: number) {
super();
}
// 重写 getArea 方法
override getArea(): number { // 使用 override 关键字
return Math.PI * this.radius ** 2;
}
}
访问修饰符
1. public(默认)
class Example {
public name: string; // 可以在任何地方访问
}
2. private
class Example {
private secretKey: string; // 只能在类内部访问
private generateKey(): string {
return Math.random().toString(36);
}
}
3. protected
class Parent {
protected data: string; // 可以在子类中访问
}
class Child extends Parent {
showData() {
console.log(this.data); // OK
}
}
4. readonly
class Config {
readonly API_KEY: string;
constructor(key: string) {
this.API_KEY = key; // 只能在构造函数中赋值
}
}
抽象类
基本用法
abstract class Vehicle {
constructor(protected brand: string) {}
// 抽象方法必须在子类中实现
abstract start(): void;
// 具体方法可以包含实现
stop(): void {
console.log("Vehicle stopped");
}
}
class Car extends Vehicle {
// 必须实现抽象方法
start(): void {
console.log(`${this.brand} car starting...`);
}
}
何时使用抽象类
- 需要定义一个基类,但基类本身不应该被实例化
- 有一些通用的实现,但部分行为需要子类特定实现
- 强制子类实现某些方法
// 示例:支付系统
abstract class PaymentProcessor {
constructor(protected amount: number) {}
// 通用的支付流程
process(): void {
this.validate();
this.doPayment();
this.sendReceipt();
}
// 具体实现
protected sendReceipt(): void {
console.log("Receipt sent");
}
// 抽象方法 - 不同支付方式有不同的验证逻辑
protected abstract validate(): void;
// 抽象方法 - 不同支付方式有不同的支付逻辑
protected abstract doPayment(): void;
}
// 信用卡支付实现
class CreditCardProcessor extends PaymentProcessor {
constructor(
amount: number,
private cardNumber: string,
private cvv: string
) {
super(amount);
}
protected validate(): void {
// 验证信用卡信息
}
protected doPayment(): void {
// 处理信用卡支付
}
}
高级特性
1. 接口实现
interface Printable {
print(): void;
}
interface Serializable {
serialize(): string;
}
// 类可以实现多个接口
class Document implements Printable, Serializable {
print(): void {
// 实现打印功能
}
serialize(): string {
// 实现序列化功能
return "";
}
}
2. 泛型类
class Container<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
const numberContainer = new Container<number>(123);
const stringContainer = new Container<string>("hello");
最佳实践
1. 封装
class BankAccount {
private balance: number = 0;
deposit(amount: number): void {
if (amount > 0) {
this.balance += amount;
}
}
getBalance(): number {
return this.balance;
}
}
2. 组合优于继承
// 不好的做法:过度继承
class Animal {}
class FlyingAnimal extends Animal {}
class SwimmingAnimal extends Animal {}
class FlyingSwimmingAnimal extends FlyingAnimal {}
// 好的做法:组合
interface Flyer {
fly(): void;
}
interface Swimmer {
swim(): void;
}
class Duck implements Flyer, Swimmer {
fly(): void {
// 实现飞行
}
swim(): void {
// 实现游泳
}
}
3. 单一职责原则
// 不好的做法
class UserManager {
saveUser() { /* ... */ }
validateEmail() { /* ... */ }
sendEmail() { /* ... */ }
}
// 好的做法
class UserRepository {
saveUser() { /* ... */ }
}
class EmailValidator {
validate(email: string) { /* ... */ }
}
class EmailService {
send(to: string, content: string) { /* ... */ }
}
总结
-
类的核心概念:
- 属性和方法封装
- 继承和多态
- 访问控制
- 抽象和实现
-
最佳实践:
- 使用适当的访问修饰符
- 优先使用组合而不是继承
- 遵循单一职责原则
- 使用抽象类定义契约
-
使用场景:
- 面向对象编程
- 代码复用
- 框架开发
- 大型应用架构