在 TypeScript 中,class
关键字也可以用于创建类,与 JavaScript 相似,但 TypeScript 增加了类型注解和类型检查的功能,使得类的使用更加安全和强大。
使用 class
关键字来定义一个类:
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHello(): void {
console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
}
}
const person1 = new Person('Alice', 25);
person1.sayHello(); // 输出:Hello, my name is Alice and I'm 25 years old.
继承在 TypeScript 中与 JavaScript 非常相似,使用 extends
关键字来实现:
class Student extends Person {
grade: number;
constructor(name: string, age: number, grade: number) {
super(name, age); // 调用父类的 constructor
this.grade = grade;
}
study(): void {
console.log(`${this.name} is studying in grade ${this.grade}.`);
}
}
const student1 = new Student('Bob', 18, 12);
student1.sayHello(); // 输出:Hello, my name is Bob and I'm 18 years old.
student1.study(); // 输出:Bob is studying in grade 12.
在 TypeScript 中,通过接口可以约束类的属性和方法。使用 implements
关键字来实现接口:
interface Animal {
sound: string;
makeSound(): void;
}
class Dog implements Animal {
sound = "Woof";
makeSound(): void {
console.log(this.sound);
}
}
class Cat implements Animal {
sound = "Meow";
makeSound(): void {
console.log(this.sound);
}
}
const dog = new Dog();
const cat = new Cat();
dog.makeSound(); // 输出:Woof
cat.makeSound(); // 输出:Meow
在这里,我们定义了一个 Animal
接口,然后使用 implements
关键字在 Dog
和 Cat
类中实现这个接口。
readonly
、private
、protected
和 public
在 TypeScript 中,类的成员(属性和方法)可以使用不同的访问修饰符来控制其可见性和访问权限。这些修饰符包括 readonly
、private
、protected
和 public
。下面让我们逐个讲解它们的作用:
readonly
:将属性设置为只读。只读属性只能在声明时或构造函数中初始化,之后无法被修改。
class Person {
readonly name: string;
constructor(name: string) {
this.name = name;
}
}
const person = new Person('Alice');
console.log(person.name); // 输出:Alice
// person.name = 'Bob'; // 错误:Cannot assign to 'name' because it is a read-only property.
private
:将属性或方法标记为私有,只能在类的内部访问,子类也不能访问。
class BankAccount {
private balance: number;
constructor(initialBalance: number) {
this.balance = initialBalance;
}
getBalance(): number {
return this.balance;
}
}
const account = new BankAccount(1000);
// console.log(account.balance); // 错误:Property 'balance' is private and only accessible within class 'BankAccount'.
console.log(account.getBalance()); // 输出:1000
protected
:与 private
类似,但在子类中仍然可以访问。
class Person {
protected name: string;
constructor(name: string) {
this.name = name;
}
}
class Student extends Person {
constructor(name: string) {
super(name);
}
greet(): void {
console.log(`Hello, my name is ${this.name}.`);
}
}
const student = new Student('Bob');
// console.log(student.name); // 错误:Property 'name' is protected and only accessible within class 'Person' and its subclasses.
student.greet(); // 输出:Hello, my name is Bob.
public
:默认的访问修饰符,所有成员都是公开的,可以在类的内部和外部访问。
class Car {
public brand: string;
constructor(brand: string) {
this.brand = brand;
}
}
const car = new Car('Toyota');
console.log(car.brand); // 输出:Toyota
car.brand = 'Honda'; // 修改属性
console.log(car.brand); // 输出:Honda
在 TypeScript 中,类的静态方法是属于类本身而不是类的实例的方法。静态方法可以通过类名直接调用,而不需要创建类的实例。它通常用于实现一些与类相关但与实例无关的功能。以下是如何在 TypeScript 中定义和使用静态方法的示例:
class MathOperations {
static add(a: number, b: number): number {
return a + b;
}
static subtract(a: number, b: number): number {
return a - b;
}
}
// 调用静态方法,无需创建实例
const sum = MathOperations.add(5, 3);
console.log(sum); // 输出:8
const difference = MathOperations.subtract(10, 4);
console.log(difference); // 输出:6
在上面的例子中,add
和 subtract
方法都被定义为了类的静态方法,所以我们可以通过类名 MathOperations
直接调用这些方法,而不需要创建类的实例。
需要注意的是,静态方法不能访问实例属性或方法,因为它们不是通过实例调用的。它们只能访问类的静态属性和方法。
class MyClass {
static staticProp = "Static property";
static staticMethod() {
console.log("Static method called");
// console.log(this.instanceProp); // 错误:Property 'instanceProp' does not exist on type 'typeof MyClass'.
}
instanceProp = "Instance property";
instanceMethod() {
console.log("Instance method called");
}
}
console.log(MyClass.staticProp); // 输出:Static property
MyClass.staticMethod(); // 输出:Static method called
const instance = new MyClass();
console.log(instance.instanceProp); // 输出:Instance property
instance.instanceMethod(); // 输出:Instance method called
set
和 get
在 TypeScript 中,你可以使用 set
和 get
关键字来创建类的属性的 setter 和 getter 方法。这使得你能够在设置和获取属性值时执行一些逻辑,以便更好地控制属性的访问和修改。以下是如何在 TypeScript 类中使用 set
和 get
的示例:
class Circle {
private _radius: number;
constructor(radius: number) {
this._radius = radius;
}
// Getter 方法
get radius(): number {
return this._radius;
}
// Setter 方法
set radius(value: number) {
if (value < 0) {
throw new Error("Radius cannot be negative.");
}
this._radius = value;
}
get area(): number {
return Math.PI * this._radius ** 2;
}
}
const circle = new Circle(5);
console.log(circle.radius); // 输出:5
circle.radius = 7; // 调用 setter
console.log(circle.radius); // 输出:7
// circle.radius = -2; // 抛出错误:Radius cannot be negative.
console.log(circle.area); // 输出:153.93804002589985
在这个例子中,我们定义了一个 Circle
类,其中 _radius
是私有属性,我们使用 get
和 set
来创建了 radius
属性的 getter 和 setter 方法。这样,当我们获取或设置 radius
属性时,就会执行相应的逻辑。