41. TypeScript类和继承
1. 类和继承定义
TypeScript
中的类和继承可以帮助我们更好地组织代码,并且使得代码更易于维护和扩展。在TypeScript
中,可以使用class
关键字来定义一个类,然后使用extends
关键字来实现继承。以下是一个简单的类和继承的示例:
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
move(distance: number = 0) {
console.log(`${this.name} moved ${distance} meters.`);
}
}
class Dog extends Animal {
bark() {
console.log("Woof! Woof!");
}
}
let dog = new Dog("Buddy");
dog.move(10);
dog.bark();
上述代码定义了两个类Animal
和Dog
,其中Dog
类继承了Animal
类。Animal
类有一个属性name
和一个方法move
,Dog
类有一个方法bark
,并且继承了Animal
类的属性和方法。在构造函数中,使用super
关键字调用了父类的构造函数。最后,创建了一个Dog
的实例,并调用了它的move
方法和bark
方法。
2. 在使用类和继承时,可以考虑以下几点:
1. 构造函数
构造函数用来初始化对象的属性,可以使用constructor
关键字来定义。在构造函数中,可以初始化对象的属性,也可以执行一些其他的操作。例如:
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHi() {
console.log(`Hi, my name is ${
this.name}.`);
}
}
2. 继承
可以使用extends
关键字来实现继承。子类继承父类的所有属性和方法,但是子类可以覆盖父类的方法,并且可以新增自己的属性和方法。例如:
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
move(distance: number = 0) {
console.log(`${this.name} moved ${distance} meters.`);
}
}
class Dog extends Animal {
bark() {
console.log("Woof! Woof!");
}
move(distance: number = 10) {
console.log(`${this.name} moved ${distance} meters.`);
}
}
3. 多态
多态是面向对象编程中的一个重要概念,它可以让不同类型的对象对同一个方法产生不同的行为。在TypeScript
中,使用继承和方法重写可以实现多态。例如,我们可以创建一个Animal
类和它的子类Dog
和Cat
,每个子类都可以实现自己的makeSound
方法:
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound(): void {
console.log('Generic animal sound');
}
}
class Dog extends Animal {
makeSound(): void {
console.log('Woof! Woof!');
}
}
class Cat extends Animal {
makeSound(): void {
console.log('Meow! Meow!');
}
}
//现在我们可以使用这些类来创建对象,并调用它们的makeSound方法:
let animal: Animal = new Animal('Animal');
let dog: Dog = new Dog('Dog');
let cat: Cat = new Cat('Cat');
animal.makeSound(); // "Generic animal sound"
dog.makeSound(); // "Woof! Woof!"
cat.makeSound(); // "Meow! Meow!"
4. 抽象类
抽象类是一种特殊的类,它不能被实例化,只能用来作为其他类的基类。抽象类可以包含抽象方法和非抽象方法,抽象方法只有声明,没有实现。子类必须实现抽象方法。例如:
abstract class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
abstract makeSound(): void;
move(distance: number = 0) {
console.log(`${this.name} moved ${distance} meters.`);
}
}
class Dog extends Animal {
constructor(name: string) {
super(name);
}
makeSound() {
console.log("Woof! Woof!");
}
}
在上面的代码中,Animal
类是一个抽象类,其中包含了一个抽象方法makeSound
和一个非抽象方法move
。Dog
类继承了Animal
类,并且实现了makeSound
方法。注意,在子类中实现抽象方法时,需要使用override
关键字。
5. 类的访问修饰符
类的成员变量和成员方法可以使用public
、private
和protected
等访问修饰符来控制访问权限。public
表示公共,可以在任何地方访问;private
表示私有,只能在类的内部访问;protected
表示受保护,可以在类的内部和子类中访问。例如:
class Person {
public name: string;
private age: number;
protected gender: string;
constructor(name: string, age: number, gender: string) {
this.name = name;
this.age = age;
this.gender = gender;
}
sayHi() {
console.log(`Hi, my name is ${
this.name}.`);
}
private sayAge() {
console.log(`I am ${
this.age} years old.`);
}
}
class Student extends Person {
constructor(name: string, age: number, gender: string) {
super(name, age, gender);
}
sayGender() {
console.log(`My gender is ${
this.gender}.`);
}
}
let person = new Person("Tom", 18, "male");
console.log(person.name); // "Tom"
console.log(person.age); // Error: Property 'age' is private and only accessible within class 'Person'.
console.log(person.gender); // Error: Property 'gender' is protected and only accessible within class 'Person' and its subclasses.
let student = new Student("Jane", 20, "female");
console.log(student.gender); // "female"
在上面的代码中,Person
类有三个成员变量name
、age
和gender
,其中name
是public
的,age
是private
的,gender
是protected
的。Student
类继承了Person
类,可以访问gender
成员变量。注意,无论成员变量是何种访问修饰符,都要显式声明类型。
总之,TypeScript
中的类和继承提供了一种更加结构化和面向对象的编程方式,可以使得代码更加易于维护和扩展。在实际开发中,应该根据实际情况来选择使用类和继承。