TypeScript - 类
TypeScript - 类
Section titled “TypeScript - 类”类是面向对象编程(OOP)中的一个基本概念,用作创建对象的蓝图。它们封装了与特定实体相关的数据(属性或字段)和行为(方法或函数)。TypeScript 对 ES6 中引入的类语法提供了第一类支持,并通过类型注解和访问修饰符进行了增强。
使用 class 关键字,后跟类名(通常使用 PascalCase)。
class ClassName { // 字段 (属性) propertyName: type; anotherProperty?: type; // 可选属性 readonly readOnlyProp: type = initialValue; // 只读属性 private privateField: type; protected protectedField: type; static staticProperty: type = value;
// 构造函数 constructor(param1: type, param2: type, ...) { // 初始化逻辑 this.propertyName = param1; // ... }
// 方法 methodName(param: type): returnType { // 方法逻辑 return value; }
private privateMethod(): void { ... } protected protectedMethod(): void { ... } static staticMethod(): void { ... }
// 获取器 (Getters) 和 设置器 (Setters) get computedValue(): type { return this.propertyName; } set computedValue(value: type) { this.propertyName = value; }}类定义可以包含:
- Fields (字段/属性): 在类作用域内声明的变量,用于存储类的实例数据。使用类型注解。
- Constructor (构造函数): 一个特殊的方法,名为
constructor,负责创建和初始化使用该类创建的对象。当您使用new关键字时会被调用。 - Methods (方法): 在类内定义的函数,定义了对象的行为。
- Access Modifiers (访问修饰符): 控制类成员可见性和可访问性的关键字(
public、private、protected)。 - Readonly Modifier (只读修饰符): 防止属性在首次赋值(通常在构造函数中)后被修改。
- Static Members (静态成员): 属于类本身而非其实例的属性或方法。通过
ClassName.memberName访问。 - Getters/Setters (获取器/设置器): 提供对对象属性进行受控访问的特殊方法。
示例:简单类
Section titled “示例:简单类”class Vehicle { // 属性,默认访问级别 (public) make: string; model: string; year: number; private _vin: string; // 私有属性约定 readonly id: string;
// 静态属性 static numberOfVehicles = 0;
constructor(make: string, model: string, year: number, vin: string) { this.make = make; this.model = model; this.year = year; this._vin = vin; this.id = `veh-${Math.random().toString(36).substr(2, 9)}`; // 为只读属性赋值 Vehicle.numberOfVehicles++; // 增加静态属性值 }
// 方法 displayInfo(): void { console.log(`Vehicle: ${this.year} ${this.make} ${this.model} (ID: ${this.id})`); }
// 私有属性的获取器 get vin(): string { return this._vin; }
// 静态方法 static getVehicleCount(): number { return Vehicle.numberOfVehicles; }}
// 访问静态成员console.log(`Initial vehicle count: ${Vehicle.getVehicleCount()}`); // 输出: 0创建实例(对象)
Section titled “创建实例(对象)”使用 new 关键字后跟类名和括号(如果需要,传递参数给构造函数)。
const car1 = new Vehicle("Toyota", "Camry", 2022, "123ABC456DEF");const car2 = new Vehicle("Honda", "Civic", 2021, "789GHI012JKL");
console.log(`Current vehicle count: ${Vehicle.getVehicleCount()}`); // 输出: 2使用点(.)符号在对象实例上访问其公共属性和方法。
console.log(car1.make); // 输出: Toyotacar1.displayInfo(); // 输出: Vehicle: 2022 Toyota Camry (ID: veh-...)
console.log(car2.model); // 输出: Civiccar2.displayInfo(); // 输出: Vehicle: 2021 Honda Civic (ID: veh-...)
// 通过获取器访问console.log(`Car 1 VIN: ${car1.vin}`);
// car1.id = "new-id"; // Error: Cannot assign to 'id' because it is a read-only property. ('id' 是只读属性,无法赋值)// console.log(car1._vin); // Error: Property '_vin' is private and only accessible within class 'Vehicle'. ('_vin' 是私有属性,只能在 'Vehicle' 类内部访问)public(默认): 成员可以从任何地方访问。private: 成员只能在其定义类内部访问。protected: 成员在其定义类内部以及派生(子)类的实例中可以访问。
参数属性简写
Section titled “参数属性简写”TypeScript 提供了一种简洁的语法,通过在构造函数参数前添加访问修饰符(public、private、protected)或 readonly,直接声明和初始化类成员。
class Employee { // 自动创建并初始化 'name' 和 'department' 属性 constructor( public readonly id: number, public name: string, private department: string ) {}
getDept(): string { // 在类内部可以访问私有成员 return this.department; }}
const emp1 = new Employee(101, "Alice", "Engineering");console.log(emp1.name); // 输出: Aliceconsole.log(emp1.id); // 输出: 101console.log(emp1.getDept()); // 输出: Engineering// console.log(emp1.department); // 错误: Property 'department' is private... ('department' 是私有属性...)继承(extends)
Section titled “继承(extends)”类可以使用 extends 关键字继承单个父类(基类或超类)的属性和方法。继承的类称为子类或派生类。
派生类继承所有公共(public)和受保护(protected)成员。私有(private)成员不被继承。构造函数不被继承,但如果父类有构造函数,则派生类的构造函数必须使用 super() 调用父类构造函数。
class Animal { constructor(public name: string) {}
move(distanceInMeters: number = 0): void { console.log(`${this.name} moved ${distanceInMeters}m.`); }}
class Dog extends Animal { // 派生类构造函数必须调用 super() constructor(name: string) { super(name); // 调用父类 (Animal) 的构造函数 }
bark(): void { console.log("Woof! Woof!"); }
// 重写父类方法 move(distanceInMeters = 5): void { console.log("Running..."); super.move(distanceInMeters); // 调用父类的 move 方法 }}
const myDog = new Dog("Buddy");myDog.bark(); // 输出: Woof! Woof!myDog.move(10); // 输出: Running... // 输出: Buddy moved 10m.console.log(myDog.name); // 输出: Buddy (继承自 Animal)方法重写和 super
Section titled “方法重写和 super”派生类可以为继承自父类的方法提供自己的实现(重写)。使用 super 关键字调用父类的方法(super.methodName())或父类构造函数(在派生类构造函数内部使用 super())。
标记为 abstract 的类不能直接实例化。它们通常用作基类,并且可能包含 abstract 方法(没有实现的方法),这些方法必须由派生类实现。
abstract class Department { constructor(public name: string) {}
printName(): void { console.log(`Department name: ${this.name}`); }
abstract printMeeting(): void; // 必须由派生类实现}
class AccountingDepartment extends Department { constructor() { super("Accounting and Auditing"); // 派生类中的构造函数必须调用 super() }
printMeeting(): void { console.log("The Accounting Department meets each Monday at 10am."); }}
// const dept = new Department("General"); // 错误: Cannot create an instance of an abstract class. (无法创建抽象类的实例)const accounting = new AccountingDepartment();accounting.printName();accounting.printMeeting();实现接口的类(implements)
Section titled “实现接口的类(implements)”类可以使用 implements 关键字实现一个或多个接口。这强制类必须遵守接口定义的结构。
interface ClockInterface { currentTime: Date; setTime(d: Date): void;}
class DigitalClock implements ClockInterface { currentTime: Date = new Date();
setTime(d: Date): void { this.currentTime = d; }}
const clock = new DigitalClock();console.log(clock.currentTime);