typescrip接口 interface详解,以及ts实现多态

2023-09-16 17:13:03

ts 接口

当一个对象类型被多次使用时,一般会使用接口(interface)来描述对象的类型,达到复用的目的
示例如下

当一个对象类型被多次使用时,可以看到,很明显代码有大量的冗余

let personTom: { name: string, age?: number, sayHi(name: string): void } = {
  name: 'Tom',
  sayHi(name: string) {
    console.log(`Hi, ${name}`)
  }
}
let personJack: { name: string, age?: number, sayHi(name: string): void } = {
  name: 'Tom',
  sayHi(name: string) {
    console.log(`Hi, ${name}`)
  }
}

这个时候可以将这个对象定义为接口,以进行复用,可以看到,这样代码就少了很多冗余

interface Person {
  name: string
  age?: number
  sayHi(name: string): void
}
let personTime: Person = {
  name: 'time',
  sayHi(name: string) {
    console.log(`hello ${name}`)
  }
}

let personJohn: Person = {
  name: 'John',
  sayHi(name: string) {
    console.log(`hello ${name}`)
  }
}

  1. 使用interface关键字来声明接口
  2. 接口名称(比如,此处的Person)可以是任意合法变量名称
  3. 声明接口后,直接使用接口名称作为变量的类型
  4. 因为每一行只有一个属性类型,因此,属性类型后没有分号或逗号

interface 与 type 类型别名的区别

在 TypeScript中,interface和type都可以用来定义类型的别名

  • 定义方式:type别名可以用来给一个类型起新名字,使用type创建类型别名。它更加灵活,可以用来定义任意类型的别名,包括原始类型、函数、对象等。而interface则是命名数据结构的另一种方式,仅限于描述对象类型,声明语法也不同于type的声明语法。
  • 使用范围:与type不同,interface仅限于描述对象类型。也就是说,interface无法用来定义非对象类型的别名,如原始类型、函数等。type则没有这些限制,可以用来定义各种类型的别名。
  • 组合类型:在TypeScript中,type可以使用交叉类型(intersection type)和联合类型(union type)来组合多个类型,而interface则不能。这意味着type可以创建更复杂和灵活的类型结构,而interface在这方面的能力较弱。
    总的来说,type和interface在TypeScript中都可以用来定义类型的别名,但它们在定义范围、组合类型的能力等方面存在明显的差异。

interface(接口)和type(类型别名)的对比

  • 相同点: 都可以给对象指定类型
  • 不同点:
    - 接口只能为对象指定类型
    - 类型别名,不仅可以为对象指定类型,实际上可以给任意类型指定别名

代码示例

interface Person {
  name: string
  age?: number
  sayHi(name: string): void
}

type animal = {
  name: string
  age?: number
  sayHi(name: string): void
}

在编译器中使用,两者都可以实现对对象的类型监测
在这里插入图片描述

接口的继承

如果两个接口之间有相同的属性或方法,可以将公共的属性或方法,抽离出来,通过继承来实现复用
比如,这两个接口都有x,y两个属性,重复写两次,可以,但是很繁琐

	interface Point2D { x: number, y: number }
	interface Point3D { x: number, y: number, z: number }

这个时候就可以使用extends继承来让Point3D 继承Point2D 就可以省去x和y的定义了
如下

	interface Point2D { x: number, y: number }
	// interface Point3D { x: number, y: number, z: number }
	interface Point3D extends Point2D { z: number }

在这里插入图片描述

tips:

  1. 使用extends(继承)关键字实现了接口Point3D 继承Point2D
  2. 继承后,Point3D 就有了Point2D的所有方法和属性了(此时Point3D 同时有x,y,z三个属性)
继承多个接口

一个接口可以继承多个接口,如下 video3D继承了video接口和3D接口 ,继承后,Video3D接口就同时拥有两个接口的所有属性和方法了

interface Point2D { x: number, y: number }
// interface Point3D { x: number, y: number, z: number }
interface Point3D extends Point2D { z: number }

interface Video { video: object }

interface Video3D extends Video, Point3D {
  lookAt(target: Point3D): void;
}


let v: Video3D = { video: {}, x: 10, y: 10, z: 10, lookAt: (t) => { } } 

typescript 多态

先看下面这个例子

interface Animal {  
    name: string;  
    age: number;  
    sound: () => void;  
}  
  
interface Dog extends Animal {  
    breed: string;  
}  
  
let myDog: Dog = {  
    name: "Rex",  
    age: 3,  
    breed: "German Shepherd",  
    sound: () => console.log("Bark!")  
};

在这个例子中,Dog 接口继承了 Animal 接口。这意味着,Dog 对象必须包含 Animal 接口定义的所有属性和方法,也就是 name、age 和 sound。然后,Dog 接口还定义了自己的额外属性,即 breed。
这是一个很有意思的现象,因为这已经是静态类型语言才能实现多态的基础了

如上在 TypeScript 中,接口继承可以实现多态性。如果你有一个函数接受 Animal 类型的参数,那么你也可以传入一个 Dog 类型的参数,因为 Dog 是 Animal 的子类型。这是基于 Liskov 替换原则,也就是子类型必须能够替换它们的基类型。
原理有了,开始实现

	//定义基类
	interface Animal {
	  name: string;
	  age: number;
	  sound: () => void;
	}
	
	//定义基础
	interface Dog extends Animal {
	  breed: string;
	}
	
	let myDog: Dog = {
	  name: "Rex",
	  age: 3,
	  breed: "German Shepherd",
	  sound: () => console.log("Bark!")
	};
	
	//实现多态
	function polymorphicDisplay(a: Animal) {
	  a.sound();
	}
	
	polymorphicDisplay(myDog);

输出成功, js牛逼! ,不对ts牛逼
在这里插入图片描述

更多推荐

【Verilog教程】2.4Verilog表达式

表达式表达式由操作符和操作数构成,其目的是根据操作符的意义得到一个计算结果。表达式可以在出现数值的任何地方使用。例如:a^b;//a与b进行异或操作address[9:0]+10'b1;//地址累加flag1&&flag2;//逻辑与操作操作数操作数可以是任意的数据类型,只是某些特定的语法结构要求使用特定的操作数。操作

Leetcode算法入门与数组丨4. 数组排序

文章目录1冒泡排序2选择排序3插入排序4归并排序5希尔排序6快速排序7堆排序8计数排序9桶排序10基数排序task05task061冒泡排序冒泡排序(BubbleSort)是一种简单的排序算法。它重复地遍历待排序的元素列表,一次比较相邻的两个元素,并按照顺序交换它们,直到整个列表排序完成。基本步骤下面是冒泡排序的基本步

【深度学习】 Python 和 NumPy 系列教程(十一):NumPy详解:3、数组数学(元素、数组、矩阵级别的各种运算)

目录一、前言二、实验环境三、NumPy0、多维数组对象(ndarray)多维数组的属性1、创建数组2、数组操作3、数组数学1.元素级别a.直接运算b.加法:np.add()函数c.减法:np.subtract()函数d.乘法:np.multiply()函数e.除法:np.divide()函数f.幂运算:np.power

WIFI6特性分析

特性介绍wifi6作为全新一代wifi协议,提供了更快速度,信道利用率更高,抗干扰能力更强,更高的频宽,更好的待机表现。下边是对比wifi456三代特性的区别:OFDMA:正交多频分址,提升物理媒介的并发通信能力。MU-MINO:多用户上传下载,提升多用处场景wifi速率160MHZ:拓展频段宽度TWT:休眠唤醒机制,

php外贸代购系统网站,淘宝代购系统,淘宝代购集运系统,海外代购系统

PHP外贸代购系统网站建设需要以下步骤:链接各大热门商城上的商品并自动获取参数,程序集成了淘宝、拍拍等大型热门商城抓取规则,可以直接一键代购上面的任何商品,自动获取相应的参数。确定网站功能,如:产品展示、在线购物、搜索引擎等。选择适合的数据库,例如MySQL、PostgreSQL等,存储网站的数据信息。根据目标用户的需

【leetcode 力扣刷题】栈—波兰式///逆波兰式相关知识和题目

波兰式、逆波兰式相关知识和题目波兰式、逆波兰式介绍常规表达式转换成逆波兰式==编程让常规表达式转换成逆波兰式==逆波兰式运算过程常规表达式转换成波兰式==编程让常规表达式转换成波兰式==波兰式运算过程150.逆波兰式表达式求值224.基本计算器227.基本计算器Ⅱ282.给表达式添加运算符波兰式、逆波兰式介绍我们常看到

计算机毕业设计 基于SpringBoot餐厅点餐系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟————————————————计算机毕业设计题目《10

个人简历内容

简历个人信息专业技能熟悉Java基础,如集合、代理、反射等。了解Java多线程,了解JVM内存模型、常见GC算法、类加载机制。·#熟悉SSM+SpringBoot框架,熟悉AOP、IOC和SpringBoot自动配置原理,了解SpringMVC执行流程。熟悉MySQL数据库,熟悉InnoDB存储引擎、事务、MVCC机制

2023年云南省职业院校技能大赛中职组“网络安全”赛项样题

2023年云南省职业院校技能大赛中职组“网络安全”赛项样题一、竞赛时间总计:180分钟二、竞赛阶段竞赛阶段任务阶段竞赛任务竞赛时间分值A、B模块A-1登录安全加固180分钟200分A-2数据库加固A-3服务加固SSH\VSFTPDA-4防火墙策略B-1隐写术应用-B400分B-2内存取证B-3数据库渗透B-4Linux

信息检索与数据挖掘 | (二)布尔检索与倒排索引

文章目录📚词项-文档关联矩阵🐇相关名词🐇词项-文档关联矩阵的布尔查询处理📚倒排索引🐇关于索引🐇建立索引🐇基于倒排索引的布尔查询处理🐇查询优化📚字典数据结构🐇哈希表🐇各种树🐇B树vsB+树📚短语查询及含位置信息的倒排记录🐇二元词索引(Biwordindexes)🐇位置信息索引🐇混合索引机制

Hadoop学习总结(搭建Hadoop集群的安装准备)

目录一、安装jdk1、查看电脑中安装的jdk版本2、安装jdk173、配置path(配置jdk)4、对jdk8和jdk17版本做自由切换二、安装vmware三、安装centos7(虚拟机)四、虚拟机设置五、虚拟机网络配置1、查看NAT的网段2、修改主机名(1)修改虚拟机的hosts(2)修改虚拟机的hostname3、

热文推荐