面试题答案
一键面试区别
- 定义本质
- 接口(interface):是一种类型定义,主要用于定义对象的形状(shape),即对象所拥有的属性和方法的签名,它不包含属性的实现和方法的具体代码。接口只能定义抽象成员,不能包含具体实现。
- 抽象类(abstract class):是一种类,它可以包含抽象成员(只有声明,没有实现),也可以包含具体实现的成员(属性和方法)。抽象类不能被直接实例化,必须通过子类继承并实现其抽象成员后才能被实例化。
- 实现方式
- 接口:类通过
implements
关键字来实现接口,一个类可以实现多个接口。 - 抽象类:类通过
extends
关键字来继承抽象类,一个类只能继承一个抽象类。
- 接口:类通过
- 数据成员
- 接口:不能包含数据成员(属性的初始化),只能定义属性的类型。
- 抽象类:可以包含数据成员,并且可以对其进行初始化。
- 静态成员
- 接口:不能定义静态成员。
- 抽象类:可以定义静态成员。
场景举例
- 接口的使用场景
- 对象形状定义:当需要定义对象的结构,例如定义一个函数的参数对象结构时非常有用。
interface User { name: string; age: number; } function greet(user: User) { console.log(`Hello, ${user.name}, you are ${user.age} years old.`); } const tom: User = { name: 'Tom', age: 25 }; greet(tom);
- 多继承行为模拟:当一个类需要实现多种不同类型的行为时,可以实现多个接口。
interface Flyable { fly(): void; } interface Swimmable { swim(): void; } class Duck implements Flyable, Swimmable { fly() { console.log('Duck is flying.'); } swim() { console.log('Duck is swimming.'); } }
- 抽象类的使用场景
- 通用逻辑提取:当多个类有一些共同的属性和方法实现,同时又有一些需要子类去具体实现的抽象部分时,使用抽象类。
abstract class Animal { name: string; constructor(name: string) { this.name = name; } abstract makeSound(): void; move() { console.log(`${this.name} is moving.`); } } class Dog extends Animal { makeSound() { console.log('Woof!'); } } class Cat extends Animal { makeSound() { console.log('Meow!'); } } const dog = new Dog('Buddy'); dog.makeSound(); dog.move();
- 框架或库的基础结构:在框架开发中,抽象类可以作为基础类,为子类提供通用的行为和属性,子类根据具体需求实现抽象方法。例如在一些图形绘制库中,可能有一个抽象的
Shape
类,包含一些通用的属性和抽象的draw
方法,具体的Circle
、Rectangle
等类继承自Shape
并实现draw
方法。