面试题答案
一键面试TypeScript 抽象类继承规则与接口实现规则协同工作
- 抽象类继承规则
- 定义抽象类:使用
abstract
关键字定义抽象类,抽象类可以包含抽象方法(只有声明,没有实现)和具体方法。例如:
abstract class Animal { abstract makeSound(): void; move(): void { console.log('Moving...'); } }
- 继承抽象类:子类通过
extends
关键字继承抽象类,并必须实现抽象类中的抽象方法。
class Dog extends Animal { makeSound(): void { console.log('Woof!'); } }
- 定义抽象类:使用
- 接口实现规则
- 定义接口:使用
interface
关键字定义接口,接口只包含方法签名等抽象成员。例如:
interface Flyable { fly(): void; }
- 实现接口:类通过
implements
关键字实现接口,必须实现接口中定义的所有成员。
class Bird extends Animal implements Flyable { makeSound(): void { console.log('Chirp!'); } fly(): void { console.log('Flying...'); } }
- 定义接口:使用
- 协同工作
- 一个类可以继承抽象类并实现多个接口。抽象类提供了部分通用实现,而接口定义了额外的行为契约。例如:
abstract class Shape { abstract getArea(): number; } interface Colorable { setColor(color: string): void; } class Rectangle extends Shape implements Colorable { constructor(private width: number, private height: number) { super(); } getArea(): number { return this.width * this.height; } setColor(color: string): void { console.log(`Setting color to ${color}`); } }
可能遇到的陷阱及避免方法
- 多重继承相关陷阱
- 陷阱:TypeScript 不支持多重继承(一个类不能同时继承多个类),但可以实现多个接口。在复杂架构中,如果过度依赖接口实现来模拟多重继承的功能,可能导致代码结构混乱,出现菱形继承问题(多个父接口或抽象类有相同的方法签名,子类实现时会冲突)。
- 避免方法:合理设计抽象类和接口,尽量将通用的实现放在抽象类中,接口只定义行为契约。如果确实需要类似多重继承的功能,可以通过组合(在类中包含其他类的实例)来替代。
- 抽象方法未实现陷阱
- 陷阱:在继承抽象类时,忘记实现抽象类中的抽象方法,TypeScript 编译器会报错,但在大型代码库中排查此类错误可能比较麻烦。
- 避免方法:在继承抽象类时,立即实现所有抽象方法。可以使用 IDE 的代码生成功能,快速生成抽象方法的实现框架,减少手动遗漏的可能性。
- 接口成员实现不一致陷阱
- 陷阱:实现多个接口时,不同接口可能有相似或相同签名的成员,在实现这些成员时可能出现不一致的情况,例如返回值类型错误或实现逻辑不同但期望相同。
- 避免方法:在设计接口时,尽量避免不同接口出现语义相似但实现要求不一致的成员。如果无法避免,在实现类中仔细检查每个接口成员的实现,确保符合所有接口的契约。
- 类型兼容性陷阱
- 陷阱:在复杂的继承和接口实现结构中,类型兼容性可能会变得复杂。例如,将一个实现了多个接口的类实例赋值给只期望其中一个接口类型的变量时,可能会出现运行时错误,因为该实例可能还有其他不相关的方法或属性。
- 避免方法:在进行类型赋值和使用时,明确类型的期望和实际实例的能力。可以使用类型断言来确保类型转换的正确性,但要谨慎使用,因为不当的类型断言可能隐藏运行时错误。同时,使用严格的类型检查(如
strict
模式)可以在编译时发现更多类型相关问题。