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.14
console.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); // 输出: John
person.name = "Jane";
console.log(person.name); // 输出: Jane
person.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 的类及其高级特性,可以显著提高代码的质量和开发效率。