1. 什么是extends关键字
在typescript中,extends是一个类继承的关键字。从父类获得属性和方法,在子类中可以通过调用super()方法,来访问父类的构造函数和方法。extends关键字包含了JavaScript中面向对象编程中的继承。
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
}
class Employee extends Person {
position: string;
constructor(name: string, position: string) {
super(name);
this.position = position;
}
}
上面的例子中,Employee类继承了Person类。Employee继承了Person的属性和方法,可以访问Person中定义的属性和调用Person中定义的方法。对于构造函数,Employee在定义时使用了super()方法来调用Person的构造函数,以保证在进行Employee实例化时能正确地执行Person的构造函数。
2. 如何使用extends关键字
2.1 继承属性和方法
使用extends关键字可以继承父类的属性和方法,让子类具有相同的特性。
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHi(): void {
console.log(`Hi, my name is ${this.name}, I am ${this.age} years old.`);
}
}
class Student extends Person {
grade: number;
constructor(name: string, age: number, grade: number) {
super(name, age);
this.grade = grade;
}
study(): void {
console.log(`I am studying in grade ${this.grade}.`);
}
}
const student1 = new Student('Tom', 18, 12);
student1.sayHi(); // Hi, my name is Tom, I am 18 years old.
student1.study(); // I am studying in grade 12.
在上面的代码中,Student类继承了Person类的属性和方法,包括name和age属性以及sayHi()方法,同时增加了grade属性和study()方法,使得Student类具有自己的特性。
2.2 调用父类的构造函数和方法
在子类的构造函数中,使用super()方法来调用父类的构造函数,并且在子类的方法内部,可以使用super.父类方法名()的方式来调用父类的方法。
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
move(distance: number = 0): void {
console.log(`${this.name} moved ${distance}m.`);
}
}
class Snake extends Animal {
constructor(name: string) {
super(name);
}
move(distance: number = 5): void {
console.log('Slithering...');
super.move(distance);
}
}
const snake1 = new Snake('Sammy');
snake1.move(); // Slithering... Sammy moved 5m.
在上面的代码中,Animal类有一个move()方法,Snake类重写了move()方法,并且在内部调用了super.move()来执行Animal类的move()方法,使得重写方法与实现父类方法可以并存。
2.3 重写父类方法
子类可以重写父类的方法,以实现不同的功能或扩展父类方法的行为。
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
move(distance: number = 0): void {
console.log(`${this.name} moved ${distance}m.`);
}
}
class Dog extends Animal {
constructor(name: string) {
super(name);
}
move(distance: number = 10): void {
console.log(`${this.name} runs ${distance}m.`);
}
}
const dog1 = new Dog('Buddy');
dog1.move(); // Buddy runs 10m.
在上面的代码中,Dog类重写了父类Animal的move()方法,使得Dog类的move()方法覆盖了Animal类的move()方法,实现了不同的功能。
2.4 使用抽象类抽象方法
在extends关键字中,通常会用到抽象类和抽象方法。抽象类不能被实例化,但可以作为其他类的基类,抽象方法只能在抽象类中定义,子类必须对抽象方法进行实现。
abstract class Animal {
abstract makeSound(): void;
move(distance: number = 0): void {
console.log(`This animal moves ${distance}m.`);
}
}
class Dog extends Animal {
makeSound(): void {
console.log('Woof! Woof!');
}
}
const dog1 = new Dog();
dog1.makeSound(); // Woof! Woof!
dog1.move(); // This animal moves 0m.
在上面的代码中,Animal类为抽象类,它的makeSound()方法是一个抽象方法,必须在子类中进行实现,而Dog类则实现了Animal类的makeSound()方法,实现了自己的特性。
3. extends关键字的优缺点
3.1 优点
继承父类的属性和方法,避免了重复代码的出现,提高了代码的重用性和可维护性。
在子类中可以扩展父类方法的行为,重写父类的方法实现不同的功能。
抽象类和抽象方法的使用,可以规范子类的实现方法。
3.2 缺点
过多的继承可能导致代码难以维护。
继承的层次过深会影响代码的性能。
过度使用继承会导致代码紧耦合,不利于代码的复用和扩展。
4. 小结
在typescript中,extends是类继承的关键字,使用extends可以继承父类的属性和方法,实现代码的重用。同时,extends关键字支持调用父类的构造函数和方法,并且可以重写父类的方法实现不同的功能。抽象类和抽象方法的使用,可以规范子类的实现方法。但过多的继承可能会影响代码的维护性和性能,过度使用继承也会导致代码紧耦合,不利于代码的复用和扩展。