TypeScript:11、接口
接口
接口用于描述对象或类应该具备的结构。它只规定属性和方法的形状,不负责创建实例,也不提供具体实现。
一、接口的基本语法
interfacePerson{name:string;sayHello():void;}这个接口要求对象必须包含:
name字符串属性。sayHello方法。
二、使用接口检查对象
接口可以作为函数参数类型:
interfacePerson{name:string;sayHello():void;}functiongreet(person:Person):void{person.sayHello();}greet({name:'孙悟空',sayHello():void{console.log('Hello,我是'+this.name);}});传入的对象只要满足接口结构,就可以作为Person使用。
三、接口的结构化类型检查
TypeScript 关注对象是否具有需要的属性和方法,而不要求对象必须来自某一个具体的类。这种方式叫结构化类型系统。
interfaceUser{name:string;age:number;}constuser={name:'孙悟空',age:18,address:'花果山'};functionprintUser(value:User):void{console.log(value.name+':'+value.age);}printUser(user);user包含User要求的属性,因此可以传给printUser。
四、类实现接口
使用implements让类实现接口:
interfacePerson{name:string;sayHello():void;}classStudentimplementsPerson{constructor(publicname:string){}sayHello():void{console.log('大家好,我是'+this.name);}}conststudent=newStudent('小明');student.sayHello();类实现接口时,必须包含接口中声明的所有属性和方法。
五、接口中的可选属性
使用?可以声明可选属性:
interfaceConfig{host:string;port?:number;}constconfigA:Config={host:'localhost'};constconfigB:Config={host:'localhost',port:3000};可选属性可能不存在,使用时要考虑undefined:
functionprintConfig(config:Config):void{if(config.port!==undefined){console.log(config.port);}}六、接口中的 readonly 属性
使用readonly可以让接口属性只能读取:
interfaceUser{readonlyid:number;name:string;}constuser:User={id:1001,name:'孙悟空'};// 编译错误:id 是只读属性// user.id = 1002;七、接口继承接口
接口可以通过extends继承其他接口:
interfaceAnimal{name:string;}interfaceDogextendsAnimal{bark():void;}constdog:Dog={name:'旺财',bark():void{console.log('汪汪叫');}};Dog同时拥有Animal的属性和自己的方法。
八、接口和类型别名的区别
接口和类型别名都可以描述对象结构,但使用习惯略有不同:
| 对比项 | interface | type |
|---|---|---|
| 描述对象结构 | 适合 | 适合 |
| 声明类的实现契约 | 常用 | 也可以使用 |
| 扩展方式 | extends | 交叉类型& |
| 联合类型 | 不直接使用 | 更方便 |
| 元组和字面量 | 可以间接描述 | 更方便 |
示例:
typeID=number|string;typePoint=[number,number];九、接口和抽象类的区别
| 对比项 | 接口 | 抽象类 |
|---|---|---|
| 是否可以包含具体实现 | 不包含 | 可以包含 |
| 是否可以有构造函数 | 不可以 | 可以 |
| 是否可以保存实现逻辑 | 不可以 | 可以 |
| 一个类可以实现多个 | 可以实现多个接口 | 通常只能继承一个类 |
| 主要作用 | 描述结构和契约 | 提供基础类和通用逻辑 |
十、常见问题
1. implements 不会自动生成方法
implements只负责检查类是否满足接口,不会自动把方法添加到类中:
interfacePerson{sayHello():void;}classStudentimplementsPerson{// 必须自己实现 sayHellosayHello():void{console.log('Hello');}}2. 接口不能直接创建对象
接口只存在于类型检查阶段,不能这样使用:
// const person = new Person();应该创建实现接口的具体类,或者创建符合接口结构的对象字面量。
十一、本章小结
- 接口用于描述对象或类的结构。
- 对象只要满足接口要求,就可以通过类型检查。
implements用于让类实现接口。- 接口支持可选属性、只读属性和接口继承。
- 接口描述结构,抽象类可以提供公共实现。
