在前端领域,TypeScript 变成了越来越受欢迎的语言。它是一个强类型的 JavaScript 超集,通过类型注解提供了更好的类型检查、代码可读性和可维护性。而 TypeScript 中的类则是实现面向对象编程的重要组成部分。在本篇文章中,我们将深入探讨 TypeScript 类的使用,并分享一些技巧和最佳实践。
定义 TypeScript 类
在 TypeScript 中创建一个类非常简单,只需要使用 class 关键字和一些基本语法即可。下面是一个简单的例子:
// www.javascriptcn.com code example
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHi() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
const alice = new Person('Alice', 30);
alice.sayHi(); // 输出:Hello, my name is Alice and I am 30 years old.在这个例子中,我们定义了一个名为 Person 的类,并声明了两个属性 name 和 age。同时,在 constructor 中我们初始化了这两个属性。最后,在 sayHi 方法中,我们输出了一个字符串,包含了当前实例的 name 和 age 属性。
在 TypeScript 中,我们可以通过其他许多方式来声明类属性和方法,例如:
// www.javascriptcn.com code example
class Person {
// 公有属性(默认)
public name: string;
// 私有属性
private age: number;
// 受保护属性
protected height: number;
// 只读属性
readonly id: number;
constructor(name: string, age: number, height: number, id: number) {
this.name = name;
this.age = age;
this.height = height;
this.id = id;
}
// 公有方法(默认)
public sayHi() {}
// 私有方法
private calculateAge() {}
// 受保护方法
protected getHeight() {}
// 抽象方法
abstract walk();
}您可以选择适当的访问修饰符来限制类的属性和方法的可见性,并使用 readonly 修饰符来确保某些属性无法被更改。您还可以定义抽象方法,这些方法在基类中声明但在子类中定义。
继承和多态
继承和多态是面向对象编程中的两个重要概念。在 TypeScript 中,我们可以通过继承和多态来扩展类的功能。
继承
继承是指子类从父类继承其属性和方法。子类可以在继承的基础上添加新属性和方法,或者覆盖父类的属性和方法。例如:
// www.javascriptcn.com code example
class Student extends Person {
grade: number;
constructor(name: string, age: number, grade: number) {
super(name, age);
this.grade = grade;
}
// 覆盖父类方法
sayHi() {
console.log(`Hello, my name is ${this.name}, I am a student at grade ${this.grade}.`);
}
// 子类特有方法
study() {
console.log(`${this.name} is studying.`);
}
}
const bob = new Student('Bob', 12, 5);
bob.sayHi(); // 输出:Hello, my name is Bob, I am a student at grade 5.
bob.study(); // 输出:Bob is studying.在这个例子中,我们定义了一个名为 Student 的子类,它从 Person 父类继承了 name 和 age 属性,同时添加了一个 grade 属性和一个 study 方法。我们还覆盖了父类的 sayHi 方法,以打印一个包含学年级的字符串。
多态
多态是指一种对象多种形态的能力,即子类可以以与父类不同的方式实现相同的方法。在 TypeScript 中,我们可以使用抽象类和接口来实现多态。例如:
// www.javascriptcn.com code example
abstract class Shape {
abstract draw(): void;
}
class Circle extends Shape {
draw() {
console.log('Drawing a circle.');
}
}
class Square extends Shape {
draw() {
console.log('Drawing a square.');
}
}
function drawShapes(shapes: Shape[]) {
shapes.forEach(shape => shape.draw());
}
const shapes = [new Circle(), new Square()];
drawShapes(shapes); // 输出:Drawing a circle. Drawing a square.在这个例子中,我们定义了一个 Shape 抽象基类和两个继承自 Shape 的子类 Circle 和 Square。我们使用抽象基类来定义一个 draw 抽象方法,这些方法在子类中被实现。最后,我们定义了一个 drawShapes 函数,它接受一个 Shape 类型的数组,并对每个元素调用其 draw 方法。
类型注解和类型推断
TypeScript 中的主要优势之一是类型系统。 TypeScript 可以通过类型注解和类型推断来确保代码的类型安全性。在 TypeScript 类中,我们可以使用这些技术来提高类的可读性和可维护性。例如:
// www.javascriptcn.com code example
class Car {
make: string;
model: string;
year: number;
private _mileage: number;
constructor(make: string, model: string, year: number, mileage: number) {
this.make = make;
this.model = model;
this.year = year;
this._mileage = mileage;
}
get mileage(): string {
return `${this._mileage.toLocaleString()} km`;
}
set mileage(value: number) {
if (value < this._mileage) {
throw new Error('Mileage cannot be decreased.');
}
this._mileage = value;
}
drive(distance: number): void {
this._mileage += distance;
}
}
const myCar = new Car('Toyota', 'Camry', 2021, 5000);
console.log(myCar.mileage); // 输出:5,000 km
myCar.drive(100);
console.log(myCar.mileage); // 输出:5,100 km
myCar.mileage = 3000; // 报错:Mileage cannot be decreased.在这个例子中,我们定义了一个 Car 类,并添加了一些属性和方法。我们使用类型注解来为每个属性和方法指定正确的类型,从而避免了许多潜在的类型错误。在 mileage 属性中,我们使用了类型推断来根据 getter 方法中的返回类型推断出该属性的类型。最后,在 drive 方法中,我们也没有指定返回类型,因为 TypeScript 可以检测到该方法不返回任何值。
总结
通过本文,我们希望您已经学会了 TypeScript 类的基本用法,并有了更深入的了解,包括继承、多态、类型注解和类型推断。同时,我们也希望您可以在自己的 TypeScript 项目中使用这些技术来提高代码的可读性、可维护性和类型安全性。
完整示例代码请访问:
https://github.com/example/typescript-examples/blob/main/src/classes.ts
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/64d435f2b5eee0b525bb0318