TypeScript 作为 JavaScript 的超集,引入了类(Class)的概念,使得开发者能够使用面向对象编程(OOP)的思想来编写更加结构化和可维护的代码。本文将详细介绍 TypeScript 中的类,包括其基本用法、高级特性、以及在实际开发中的应用。
1. 什么是类?
类是面向对象编程的核心概念。它是对象的模板,定义了对象的属性和方法。通过类,开发者可以创建具有相同属性和方法的多个对象实例。
2. 类的基本用法
2.1 定义类
在 TypeScript 中,使用 class 关键字定义类。类可以包含属性和方法。
class Person {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}greet() {console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);}}let john = new Person("John", 30);john.greet(); // 输出: Hello, my name is John and I am 30 years old.
在上述示例中,定义了一个 Person 类,包含两个属性 name 和 age,以及一个构造函数和一个方法 greet。
2.2 构造函数
构造函数用于创建和初始化类的实例。它是一个特殊的方法,在实例化类时自动调用。
class Car {make: string;model: string;year: number;constructor(make: string, model: string, year: number) {this.make = make;this.model = model;this.year = year;}displayInfo() {console.log(`Car: ${this.make} ${this.model}, Year: ${this.year}`);}}let myCar = new Car("Toyota", "Corolla", 2021);myCar.displayInfo(); // 输出: Car: Toyota Corolla, Year: 2021
2.3 参数属性
参数属性是一种简写语法,可以在构造函数的参数中直接声明和初始化成员属性。
class User {constructor(public username: string, private password: string) {}displayUsername() {console.log(`Username: ${this.username}`);}}let user = new User("john_doe", "secure_password");user.displayUsername(); // 输出: Username: john_doe// console.log(user.password); // 错误: 属性“password”为私有属性,只能在类“User”中访问
2.4 this 类型
在类的方法中,this 表示当前实例。TypeScript 允许使用 this 类型来实现方法链式调用。
class Calculator {private value: number = 0;add(num: number): this {this.value += num;return this;}subtract(num: number): this {this.value -= num;return this;}getValue(): number {return this.value;}}let calc = new Calculator();let result = calc.add(10).subtract(5).getValue();console.log(result); // 输出: 5
3. 类的继承和多态
3.1 类的继承
继承是 OOP 的一个重要特性,允许一个类继承另一个类的属性和方法。
class Employee extends Person {employeeId: number;constructor(name: string, age: number, employeeId: number) {super(name, age);this.employeeId = employeeId;}work() {console.log(`${this.name} is working.`);}}let jane = new Employee("Jane", 28, 1234);jane.greet(); // 输出: Hello, my name is Jane and I am 28 years old.jane.work(); // 输出: Jane is working.
3.2 多态
多态是指不同对象对同一操作具有不同的响应方式。可以通过继承和接口实现多态。
class Animal {speak() {console.log("Animal makes a sound.");}}class Dog extends Animal {speak() {console.log("Dog barks.");}}class Cat extends Animal {speak() {console.log("Cat meows.");}}function makeSound(animal: Animal) {animal.speak();}let dog = new Dog();let cat = new Cat();makeSound(dog); // 输出: Dog barks.makeSound(cat); // 输出: Cat meows.
4. 高级特性
4.1 抽象类
抽象类是不能被实例化的类,只能被继承。抽象类可以包含抽象方法,抽象方法没有具体实现,必须在派生类中实现。
abstract class Animal {abstract speak(): void;move() {console.log("Moving...");}}class Dog extends Animal {speak() {console.log("Dog barks.");}}let dog = new Dog();dog.speak(); // 输出: Dog barks.dog.move(); // 输出: Moving...
4.2 接口
接口是定义对象结构的另一种方式,可以用于实现多继承。类可以实现一个或多个接口。
interface Drivable {drive(): void;}interface Flyable {fly(): void;}class FlyingCar implements Drivable, Flyable {drive() {console.log("Driving...");}fly() {console.log("Flying...");}}let car = new FlyingCar();car.drive(); // 输出: Driving...car.fly(); // 输出: Flying...
4.3 静态成员
静态成员(属性和方法)属于类而不是类的实例。它们可以使用 static 关键字定义。
class MathUtil {static PI: number = 3.14;static calculateArea(radius: number): number {return this.PI * radius * radius;}}console.log(MathUtil.PI); // 输出: 3.14console.log(MathUtil.calculateArea(10)); // 输出: 314
4.4 成员存取器
成员存取器用于对类属性进行更精细的控制,包括 getter 和 setter。
class Person {private _name: string;constructor(name: string) {this._name = name;}get name(): string {return this._name;}set name(newName: string) {if (newName) {this._name = newName;} else {console.log("Invalid name");}}}let person = new Person("John");console.log(person.name); // 输出: Johnperson.name = "Jane";console.log(person.name); // 输出: Janeperson.name = ""; // 输出: Invalid name
4.5 索引签名
索引签名允许定义动态的属性名称和类型。
class Dictionary {[key: string]: string;addEntry(key: string, value: string) {this[key] = value;}}let dict = new Dictionary();dict.addEntry("hello", "world");console.log(dict.hello); // 输出: world
4.6 类类型
接口可以用来定义类的类型,使得接口不仅可以描述对象,还可以描述类的构造函数。
interface PersonConstructor {new (name: string, age: number): PersonInterface;}interface PersonInterface {name: string;age: number;greet(): void;}class Person implements PersonInterface {constructor(public name: string, public age: number) {}greet() {console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);}}function createPerson(ctor: PersonConstructor, name: string, age: number): PersonInterface {return new ctor(name, age);}let john = createPerson(Person, "John", 30);john.greet(); // 输出: Hello, my name is John and I am 30 years old.
5. 实际应用中的类
在实际开发中,类广泛应用于各种场景,如创建组件、实现业务逻辑、封装数据等。
5.1 创建组件
在前端框架如 Angular 中,类用于定义组件。
import { Component } from '@angular/core';@Component({selector: 'app-root',template: `<h1>Hello, {{ name }}</h1>`})export class AppComponent {name = 'Angular';}
5.2 实现业务逻辑
类用于封装业务逻辑,使得代码更加模块化和易于维护。
class Order {constructor(public orderId: number, public customerName: string) {}calculateTotal(items: { price: number, quantity: number }[]): number {return items.reduce((total, item) => total + item.price * item.quantity, 0);}}let order = new Order(1, "John Doe");let total = order.calculateTotal([{ price: 10, quantity: 2 }, { price: 20, quantity: 1 }]);console.log(`Total: $${total}`); // 输出: Total: $40
5.3 封装数据
类可以用于封装数据,使得数据访问更加安全和一致。
class User {private password: string;constructor(public username: string, password: string) {this.password = password;}checkPassword(password: string): boolean {return this.password === password;}}let user = new User("john_doe", "secure_password");console.log(user.checkPassword("secure_password")); // 输出: true
结论
通过本文的介绍,我们深入了解了 TypeScript 中的类及其在面向对象编程中的应用。类是 OOP 的核心概念,通过抽象、封装、继承和多态,使得代码更加模块化、复用性和可维护性。在实际开发中,合理使用 TypeScript 的类及其高级特性,可以显著提高代码的质量和开发效率。
