ArkTS-接口和泛型
接口的声明和使用
接口通过interface关键字声明,描述对象应具备的属性和方法。简单来说就是规定实现接口的类必须包含哪些属性,哪些方法。
interface接口名称{属性名:类型 方法名:返回值类型}和类不一样的是,接口没有具体的实现。其里面的属性和方法只有声明,没有具体属性值和方法体。
接口的继承
接口通过extends和继承其他接口。一个接口可继承多个父接口。
interfaceDeviceBase{name:string;status:string;deviceType:string;}interfaceDeviceController{turnOn():void;turnOff():void;getStatus():string;}interfaceIDeviceextendsDeviceBase,DeviceController{location:string;}继承后,新增的接口就会继承父接口的所有属性和方法
接口的实现
类通过implement实现接口,并完成所有成员的具体实现。一个类可以实现多个接口。
classAirConditionerimplementsDeviceBase,DeviceController{name:string='';status:string='';deviceType:string='';constructor(name:string,status:string,type:string){this.name=name;this.status=status;this.type=type;}turnOn():void{this.status='on';}turnOff():void{this.status='off';}getStatus():void{return`${this.name}的状态为${this.status}`;}}let airConditioner=newAirConditioner('空调','on','Airconditioner');注意,和抽象类不一样的是,类在实现接口的时候,必须把接口里要求的所有属性和方法都实现了。
同时,抽象类也可以实现接口,且同样可以将接口里的方法拖到下一级子类实现(不实现即可)
接口与抽象类的区别
| 接口 | 抽象类 | |
|---|---|---|
| 核心作用 | 定义结构契约,强制类遵循统一规范 | 定义基类模板,提供部分实现并约束子类 |
| 成员类型 | 仅含属性声明、方法声明 | 可含属性、普通方法(有实现)、抽象方法 |
| 继承/实现 | 类可以实现多个接口(多实现),接口可以继承多个接口(多继承) | 类只能继承一个抽象类(单继承) |
| 静态成员 | 不支持静态属性/方法 | 支持静态属性/方法 |
| 访问修饰符 | 成员默认public(不可显示添加其他修饰符) | 支持public/private/protected修饰符 |
泛型
泛型是一种参数化多态计数,允许在定义函数、类或接口时使用类型参数代替具体类型,让类、函数、接口能适配多种数据类型,同时保持类型校验,避免重复编写相似逻辑。
泛型函数
function函数名<T>(参数:T):T{函数体}其中,作为代替类型的T可替换为多种数据类型,代表任何类型。
functionidentity<T>(arg:T):T{returnarg;}//使用方式,用作类型推断letstr=indentity<string>('light');letnum=indentity<number>(26);letbool=indentity<boolean>(true);泛型类
class类名<T>{属性名:T=属性值方法名():T{}}泛型接口
interface接口名<T>{属性名:T方法名():T}泛型接口和泛型类倒是没什么好说的,和泛型函数差不多,就是把原来的类型换成泛型T。
泛型使用
classDevice<T>{privatestatus:T;constructor(initial:T){this.state=initialState;}updateState(newState:T):void{this.state=newState;console.log('状态更新为',this.state);}}//管理灯光开关letlightSwitch=newDevice<boolean>(false);lightSwitch.updateState(true);//管理空调温度letacTemp=newDevice<number>(26);acTemp.updateState(28);泛型默认值
泛型默认值允许开发者在不显式指定参数类型时,为参数类型或提供默认类型,从而简化代码并怎强灵活性
classDeviceQueue<T=Device>{privatedevices:T[]=[];//存储设备的数组,类型为T[]//入队:添加任意类型的设备enqueue(device:T):void{this.devices.push(devcie);console.log(`${JSON.stringify(device)}已接入队列`)}}classDevice{name:string='';constructor(name:string){this.name=name;}}letlightQueue=newDeviceQueue();lightQueue.enqueue(newDevice('空调设备'));letlightQueue=newDeviceQueue<string>();lightQueue.enqueue('ArkTS');泛型约束
泛型约束是让泛型只能接收特定类类型(或实现了特定接口)的参数,避免泛型被滥用,同时让编译器明确知道泛型拥有的能力,从而提供更精准的类型提示和安全校验。
classDeviceQueue<TextendsDevice>{privatedevices:T[]=[];enqueue(device:T):void{this.devices.push(devcie);console.log(`${JSON.stringify(device)}已接入队列`)}}//let stringQueue = new DeviceQueue<string>(); 如果这么调用就会报错,因为限定为Device以及其子类在实际应用时,需要注意以下几点:
- 此处的
extends表示泛型约束,并非类/接口的继承;- 泛型约束可限定泛型类型为约束类型本身及其所有子类,支持传入约束类的任意子类;
- 而普通类继承仅建立子类与单个父类的继承关系,不能直接使用父类的其他子类,二者逻辑相似但作用范围不同。