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

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牛逼
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/402489.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java Web(七)__Tomcat(二)

Tomcat工作模式 Tomcat作为Servlet容器,有以下三种工作模式。 1)独立的Servlet容器,由Java虚拟机进程来运行 Tomcat作为独立的Web服务器来单独运行,Servlet容器组件作为Web服务器中的一部分而存在。这是Tomcat的默认工作模式。…

一文弄明白KeyedProcessFunction函数

引言 KeyedProcessFunction是Flink用于处理KeyedStream的数据集合,它比ProcessFunction拥有更多特性,例如状态处理和定时器功能等。接下来就一起来了解下这个函数吧 正文 了解一个函数怎么用最权威的地方就是 官方文档 以及注解,KeyedProc…

Observability:使用 OpenTelemetry 和 Elastic 监控 OpenAI API 和 GPT 模型

作者: 来自 Elastic David Hope ChatGPT 现在非常火爆,甚至席卷了整个互联网。 作为 ChatGPT 的狂热用户和 ChatGPT 应用程序的开发人员,我对这项技术的可能性感到非常兴奋。 我看到的情况是,基于 ChatGPT 的解决方案将会呈指数级…

C++实现归并排序题目

目录 例1 例2 例3 例4 例1 912. 排序数组 参考代码 class Solution { public:vector<int> tmpnums;vector<int> sortArray(vector<int>& nums) {tmpnums.resize(nums.size());mergeSort(nums, 0, nums.size() - 1);return nums;}void mergeSort(vector…

如何使用rocketmq实现分布式事务?

什么是rocketmq事务消息 事务消息是 Apache RocketMQ 提供的一种高级消息类型&#xff0c;支持在分布式场景下保障消息生产和本地事务的最终一致性。 RocketMQ的分布式事务又称为“半消息事务”。 事务消息处理流程 RocketMQ是靠半消息机制实现分布式事务 事务消息&#x…

OpenAI 的 GPTs 提示词泄露攻击与防护实战:防御卷(一)

前面的OpenAI DevDay活动上&#xff0c;GPTs技术的亮相引起了广泛关注。随着GPTs的创建权限开放给Plus用户&#xff0c;社区里迅速涌现了各种有趣的GPT应用&#xff0c;这些都是利用了Prompt提示词的灵活性。这不仅展示了技术的创新潜力&#xff0c;也让人们开始思考如何获取他…

C++学习Day09之系统标准异常

目录 一、程序及输出1.1 系统标准异常示例1.2 标准异常表格 二、分析与总结 一、程序及输出 1.1 系统标准异常示例 #include<iostream> using namespace std; #include <stdexcept> // std 标准 except 异常class Person { public:Person(int age){if (age <…

短小精悍的npm入门级保姆教程,一篇包会

npm是什么&#xff1f; npm是一个强大的包管理工具&#xff0c;它使开发人员能够轻松地安装、更新和管理项目依赖的包。通过初始化一个package.json 文件&#xff0c;我们可以描述你的项目并记录其依赖关系。使用npm install命令&#xff0c;我们可以安装和管理包。使用npm pu…

SQL注入漏洞解析

什么是SQL注入 原理&#xff1a; SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理员不知情的情况下实现非法操作&#xff0c;以此来实现欺骗数据库服…

消息中间件之RocketMQ源码分析(十三)

Broker消息存储机制 RocketMQ首先将消息数据写入操作系统PageCache&#xff0c;然后定时将数据刷入磁盘。接下来主要分析RocketMQ是如何接收发送消息请求并将消息写入PageCache的&#xff0c;整个过程如图 Commit目录下有多个CommitLog文件&#xff0c;其实CommitLog只有一个…

前端构建效率优化之路

项目背景 我们的系统&#xff08;一个 ToB 的 Web 单页应用&#xff09;前端单页应用经过多年的迭代&#xff0c;目前已经累积有大几十万行的业务代码&#xff0c;30 路由模块&#xff0c;整体的代码量和复杂度还是比较高的。 项目整体是基于 Vue TypeScirpt&#xff0c;而构…

PostgreSQL与MySQL,谁更胜一筹

前言 PostgreSQL与MySQL都是优秀的开源数据库。在日常学习中&#xff0c;新手可能接触最多的是MySql,但是实际工作中&#xff0c;两者的应用场景其实都很广。我之前的做过上网流量销售业务&#xff0c;用的是MySQL,现在接触广告业务&#xff0c;用的是pg数据库&#xff0c;每天…

C语言:指针(一)

目录 1.内存和地址2. 指针变量和地址2.1 取地址操作符&#xff08;&&#xff09;2.2 指针变量和解引用操作符&#xff08;*&#xff09;2.2.1 指针变量2.2.2 解引用操作符&#xff08;*&#xff09; 2.3 指针变量的大小 3.指针变量的类型和意义3.1 指针的解引用3.2 指针 -指…

SQL注入漏洞解析--less-3

1.首先我们打开第三关看一下 2.这个和之前1.2关提示都是一样&#xff0c;所以我们先输入id数字看一下显示什么 3.这里正常回显&#xff0c;当我们后边加上时可以看到页面报错信息。可推断sql语句是单引号字符型且有括号&#xff0c;所以我们需要闭合单引号且也要考虑括号。 4…

FISCO BCOS(十七)利用脚本进行区块链系统监控

要利用脚本进行区块链系统监控&#xff0c;你可以使用各种编程语言编写脚本&#xff0c;如Python、Shell等 利用脚本进行区块链系统监控可以提高系统的稳定性、可靠性&#xff0c;并帮助及时发现和解决潜在问题&#xff0c;从而确保区块链网络的正常运行。本文可以利用脚本来解…

java使用File创建空文件和创建单级文件、多级文件、删除、获得文件夹下的文件和文件夹

1、使用createNewFile创建文件 package com.controller;import org.springframework.web.bind.annotation.*;import java.io.File; import java.io.IOException; import java.util.LinkedList;RestController CrossOrigin RequestMapping("/admin") public class Ad…

IO进程线程作业day5

1> 将互斥机制的代码实现重新敲一遍 #include <myhead.h> int num520;//定义一个全局变量 pthread_mutex_t mutex;//创建锁 //线程1任务 void *task1(void *arg) {puts("任务1");pthread_mutex_lock(&mutex);//上锁num1314;sleep(1);printf("tas…

Liunx使用nginx和http搭建yum-server仓库

文章目录 1. yum-server的搭建方式2. nginx搭建yum-server仓库2.1. 安装配置nginx2.2 配置yum-server的rpm2.3. 同步yum源相关包2.3.1 rsync同步源3.3.1 reposync同步源 2.4. 配置客户端访问yum配置2.5. 验证测试 3. http服务搭建yum-server仓库3.1. 安装配置http3.2 配置yum-s…

代码随想录算法训练营第一天

● 今日学习的文章链接和视频链接 ● 自己看到题目的第一想法 1. 704二分法&#xff1a; 方法一&#xff1a; 整个数组是 左闭右闭区间 [ ] left指针指向数组开始下标&#xff0c; right 指针指向数组最后下表nums.size()-1, mid为 (leftright) /2循环条件 left<rightnu…

论文精读--Noisy Student

一个 EfficientNet 模型首先作为教师模型在标记图像上进行训练&#xff0c;为 300M 未标记图像生成伪标签。然后将相同或更大的 EfficientNet 作为学生模型并结合标记图像和伪标签图像进行训练。学生网络训练完成后变为教师再次训练下一个学生网络&#xff0c;并迭代重复此过程…