博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
④TypeScript 接口(属性接口、函数类型接口、可索引接口、类类型接口、接口扩展)
阅读量:3965 次
发布时间:2019-05-24

本文共 6092 字,大约阅读时间需要 20 分钟。

TypeScript


写下博客主要用来分享知识内容,并便于自我复习和总结。

如有错误之处,请各位大佬指出。


在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范。在程序设计里面,接口起到一种限制和规范的作用。接口定义了某一批类所需要遵守的规范,它不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。Typescript中的接口类似于java,同时还增加了更灵活的接口类型,包括属性、函数、可索引和类等。


属性接口

首先,如果我们想自定义方法来实现对json数据的约束:

function printLabel(labelInfo:{
label:string}):void{
console.log("printLabel");}// 现在还不满足重用性function printLabel2(labelInfo:{
label:string}):void{
console.log("printLabel2");}// printLabel("李四"); // 错误写法// printLabel({name:"李四"}); // 错误写法printLabel({
label:"李四"}); // 正确写法

这么操作很不方便。如果对象中存储很多数据,这么做约束太不灵活了。并且,现在也不满足重用性,如果其它函数也想用它,就得再次声明。

接口就可以帮我们完成这项工作。

接口就是行为和动作的规范,并能对批量方法传入的参数进行约束。接口的关键字:interface

// 传入对象的约束:属性接口interface FullName {
// 约束我们一定要传入以下参数,并且注意数据类型 firstName: string secondName: string}function printName(name:FullName):void{
console.log(name.firstName + name.secondName);}printName({
firstName: "李", secondName: "四"})

Webstorm还很贴心的为我们做了标记:

在这里插入图片描述
那么如果我们不按照约束可以吗:

// 传入对象的约束:属性接口interface FullName {
// 约束我们一定要传入以下参数,并且注意数据类型 firstName: string secondName: string}function printName(name:FullName):void{
console.log(name.firstName + name.secondName);}printName({
firstName: "李", secondName: "四", age: 20})

此时我们可以发现,ts会报错说,接口中不存在这样的一个参数:

在这里插入图片描述
但是!页面是肯定可以输出age的内容的。看一下js中的内容就明白了。

在这里插入图片描述

虽然在ts中,这么传递参数会报错,但其实有一种可以越过检测的方式:

// 传入对象的约束:属性接口interface FullName {
// 约束我们一定要传入以下参数,并且注意数据类型 firstName: string secondName: string}function printName(name:FullName):void{
console.log(name.firstName + name.secondName); // 虽然不报错,但是在ts中使用age,依然会报错 console.log(name.age);}let obj = {
age: 20, firstName: "李", secondName: "四"}// 这么传参,虽然age不存在接口中,但是不会报错printName(obj)

此时,我们可以发现,在传递参数时已经不会报错了,但是,如果我们想使用age,那肯定会报错了,因为在接口中不存在。

在这里插入图片描述
同样的,在页面中肯定能输出age的数据。

那如果我们现在想传递这个age参数,一种方法就是在接口中直接定义了。那如果有的函数想用age,有的函数不想用age,该怎么做?

我们也可以使用可选参数:

interface FullName {
firstName: string secondName: string age?:number}function printName(name:FullName):void{
console.log(name.firstName + name.secondName);}function printAge(info:FullName):void{
console.log(info.firstName + info.secondName + info.age);}printName({
firstName: "李", secondName: "四"})// 传递参数没有顺序printAge({
age: 20, secondName: "四", firstName: "李"})

这样无论传参不传参age都不会报错了。


除此以外,还有一种定义参数的方式:

interface FullName {
firstName: string secondName: string age?:number // 参数名是string类型,可以给它一个any类型数据 [propname:string]:any}function printName(name:FullName):void{
console.log(name.sex);}printName({
firstName: "李", secondName: "四", sex: "男"})

此时,我们就可以传入一个比较随意的参数了。


最后还是要说,虽然我们可以不管ts报错信息,不管接口规范,它在页面中也能展示信息,但既然选择使用ts,那显然这些规范是必须遵守的。

实例:

interface Config {
type: string; url: string; data?:string; dataType: string;}// 原生js封装ajax,不支持ie6function ajax(config:Config){
let xhr = new XMLHttpRequest(); xhr.open(config.type,config.url, true); xhr.send(config.data); xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
console.log('成功'); if(config.dataType == 'json'){
JSON.parse(xhr.responseText); }else{
console.log(xhr.responseText) } } }}ajax({
type: 'get', url: '', //填写相关api接口 dataType: 'json', data: 'name=zhangsan'})

函数类型接口

函数类型接口:对方法传入的参数以及返回值进行约束。

interface FullName {
say():string}function printName(name:FullName):void{
console.log(name.say())}printName({
say(){
return "我是李四" }})
// 匿名函数类型接口interface encrypt {
(key:string,value:string):string;}// 一定要遵守接口约束let md5:encrypt = function(key:string,value:string):string{
// 模拟操作 return key+value;}console.log(md5("name","李四"))

对于属性接口,毕竟可以对批量传参进行约束,看起来还是有用的。那看到函数类型接口,确实会有人觉得很没用,因为函数本身就可以对参数和返回值进行约束。之前已经说过,接口也是一种标准,确实函数本身也能对这些内容进行限制,但是如果接触到了项目就会明白,有一个相关说明和规范是多么重要。并且,如果接口中设计的内容再多一些,那为了满足重用性,使用这种方式也是必然。

(当然,一般情况下,公司项目组会提供相关接口文档api)

现在已经接触到了三种规范:接口、多态、抽象类。


可索引接口

可索引接口:对数组、对象的约束(不常用)。

// 可索引接口:对数组的约束interface UserArr{
[index:number]:string;}let arr:UserArr = ['a','b','c'];console.log(arr[0]);// 可索引接口:对对象的约束interface UserObj{
[index:string]:string;}let arr1:UserObj = {
name: '李四'};console.log(arr1.name);

类类型接口

类类型接口:对类的约束,和抽象类很相似。

interface Animal{
name:string; eat(str:string):void;}// 实现接口用关键词implementsclass Dog implements Animal{
name:string; constructor(name:string) {
this.name = name; } // 必须实现方法,但是参数和数据类型不必相同 eat():string{
console.log(this.name + '吃肉') return this.name; }}let d = new Dog('旺财');console.log(d.eat());

接口扩展

接口扩展:接口可以继承接口。

interface Animal{
eat():void;}interface Person extends Animal{
work():void;}// 实现接口用关键词implementsclass Web implements Person{
name:string; constructor(name:string) {
this.name = name; } // 不仅要实现相应接口中的属性和方法, // 还要实现接口继承的接口中的属性和方法, // 否则报错 eat():void{
console.log(this.name + '吃饭'); } work():void{
console.log(this.name + '工作'); }}let my = new Web('李四');my.eat();my.work();

类可以在实现接口的同时继承父类。

interface Animal{
eat():void;}interface Person extends Animal{
work():void;}class Programmer{
name:string; constructor(name:string) {
this.name = name; } coding(code:string){
console.log(this.name + code) }}class Web extends Programmer implements Person{
constructor(name:string) {
super(name) } eat():void{
console.log(this.name + '吃饭'); } work():void{
console.log(this.name + '工作'); }}let my = new Web('李四')my.coding('写ts代码')

到此为止,已经可以看出,接口和抽象类的区别:

1、抽象类需要用abstract关键词,接口需要用interface关键词;
2、抽象类和接口都是其它类的定义规范,不能直接被实例化;
3、类想使用抽象类,需要用extends继承抽象类。类想使用接口,需要用implements实现接口。除此以外,接口也可以使用接口,需要用extends继承接口。
4、抽象方法只能存放在抽象类中,它不包含具体实现并且必须在派生类中实现,而且严格遵守传入参数数量和数据类型。抽象类中也可以有非抽象方法,在继承抽象类的子类中,不需要一定去实现非抽象方法。而接口中的所有属性和方法都必须实现,但参数和数据类型不用严格对照。


最后还有一点需要说明:接口只是帮我们在TS中完成校验的功能,它并不会转化成JS代码。而反观抽象类,它会转化成相应的JS代码。感兴趣的话,快去TS中试试吧。

转载地址:http://dmyki.baihongyu.com/

你可能感兴趣的文章
CAN总线基础知识(二)
查看>>
DM8148的电源和地(二)
查看>>
基于陀螺进行运动检测的电子稳像方案
查看>>
数字视频基础(一)
查看>>
AM5728概述(1)
查看>>
AM5728概述(4)
查看>>
AM5728概述(6)
查看>>
RapidIO协议(1)
查看>>
RapidIO协议(2)
查看>>
DM8168 EMAC/MDIO模块(2)
查看>>
DM8168 EMAC/MDIO模块(3)
查看>>
DM8168 EMAC/MDIO模块(4)
查看>>
DM8168 EMAC/MDIO模块(5)
查看>>
DM8168 EMAC/MDIO模块(6)
查看>>
DM8168 EMAC/MDIO模块(7)
查看>>
DM8168 EMAC/MDIO模块(8)
查看>>
TVP5158的多路复用技术
查看>>
DM8168 HDVPSS的VIP Parser模块(1)
查看>>
DM8168 HDVPSS的VIP Parser模块(2)
查看>>
DM8168 HDVPSS的VIP Parser模块(5)
查看>>