接口
就是用代码描述一个对象必须有什么属性(包括方法),但是有没有其他属性就不管了
理解 函数和方法的区别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 当一个函数是一个对象的属性的时候,我们把这个函数称为该对象的方法
------------ // 这是一个函数 function fn(){ console.log(1) }
let obj = { fn:function(){ console.log(2) } }
// obj.fn 就是一个方法
------------------------ 如果这样呢? function fn(){ console.log(1) } let obj = { fn:fn }
// fn实质就是 一个形如 addr = 2311111 的地址的内存 // 如果是普通编程角度 fn 是函数 // 如果是面向对象角度 fn 是方法
|
定义一个接口 人
1 2 3 4 5 6 7
| interface Human{ name:string, age:number }
let p1:Human = {name:'hjx',age:18}; // 不加 name 报错,不加age也报错
|
需求添加:人有身体
1 2 3 4 5 6 7 8 9 10 11 12
| interface Shape{ head:string, body:string }
interface Human{ name:string, age:number, shape:Shape }
let p1:Human = {name:'hjx',age:18,shape:{head:'头',body:'方的'}}
|
需求添加:人不仅有身体,还要走路
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| interface Shape{ head:string, body:string }
interface Human{ name:string, age:number, shape:Shape, say(word: string):void; }
let p1:Human = { name:'hjx', age:18, shape:{head:'头',body:'方的'}, say(word: string){ console.log(word) } }
p1.say('I\'m hjx')
|
只读属性。需求添加:人不能改名字
1 2 3 4 5 6 7 8 9 10
| interface Human{ readonly name:string, age:number }
let p1:Human = {name:'hjx',age:18};
p1.name = 'aaa' // 报错 // Cannot assign to 'name' because it is a constant or a read-only property.
|
可选属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| interface Shape{ head:string, body:string }
interface Human{ readonly name :string, age:number, shape:Shape, likedGame?:Array<string>; say(word: string):void; }
let p1:Human = { name:'hjx', age:18, shape:{head:'头',body:'方的'}, likedGame:['王者荣耀','lol'], say(word: string){ console.log(`${this.name}-${word}`); } }
let p2:Human = { name:'hjx2', age:20, shape:{head:'头',body:'方的'}, say(word: string){ console.log(`${this.name}-${word}`); } }
|
接口应用在函数里
1 2 3 4 5 6 7 8 9 10 11 12
| interface RectConfig{ height?: number, width?: number }
function createRect(config:RectConfig):void{
}
// 由于可选 所以可以传递一个属性 let mySquare = createRect({width:100}) let mySquare2 = createRect({height:100})
|
1
| let mySquare3 = createRect({width:100,height:100,color:'red'})
|
1 2 3 4 5 6 7 8 9
| let config = { height:100, width:100, color:'red' } let mySquare4 = createRect(config);
let config2 = {} //这样也可以 ,因为接口定义的参数都是可选的
|
都可选,同时受你控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| interface RectConfig{ height?: number; width?: number; [propName: string]: number; }
let config = { height:100, width:100, }
/* [propName: string] 代表 key 是一个string [propName: string]: number; 代表 key 对应的 value值必须是 number */
|
给函数定义接口
1 2 3 4 5 6 7
| interface 二则运算{ (a: number,b: number): number; }
let add:二则运算 = function(c: number, d: number): number{ return c + d; }
|
- 接口里定义一个函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| interface 二则运算{ (a: number,b: number): number; 逆运算(a: number,b: number): number; }
let add:二则运算=( (): 二则运算 =>{ let x: any = function(a: number,b: number){ return a + b; } x.逆运算 = function(a: number,b: number): number{ return a - b; } return x; } )();
console.log(add(1,2)); // 3
|
接口的继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| interface Animal{ move(): void; }
interface Human extends Animal{ name: string; age: number; }
let p: Human = { name:'hjx', age:18, move(){ console.log('我在动') } }
p.move();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| interface 有机物{ c:boolean; h:boolean; o:boolean, }
interface Animal{ move(): void; }
interface Human extends Animal,有机物{ name: string; age: number; }
let p: Human = { c:true, h:true, o:true, name:'hjx', age:18, move(){ console.log('我在动') } }
p.move();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| interface 有机物{ c:boolean; h:boolean; o:boolean, }
interface Animal extends 有机物{ move(): void; }
interface Human extends Animal{ name: string; age: number; }
let p: Human = { c:true, h:true, o:true, name:'hjx', age:18, move(){ console.log('我在动') } }
p.move();
|
一个接口继承了两个接口,顺序重要吗?
- 不重要
- 但是如果那两个接口拥有一个共同的属性就麻烦了,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| interface 有机物{ c:boolean; h:boolean; o:boolean; xxx:string; }
interface Animal{ move(): void; xxx:number }
// 继承的两个接口存在相同属性,没有覆盖关系,直接报错 interface Human extends Animal,有机物{ name: string; age: number; }
|
串行也报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| interface 有机物{ c:boolean; h:boolean; o:boolean; xxx:string; }
interface Animal extends 有机物{ move(): void; xxx:number; }
interface Human extends Animal{ name: string; age: number; }
|
除非类型一致
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| interface 有机物{ c:boolean; h:boolean; o:boolean; xxx:string; }
interface Animal extends 有机物{ move(): void; xxx:string; }
interface Human extends Animal{ name: string; age: number; }
|
接口的顺序写在后面可以吗?
- 最好不要瞎写
- ts最烦的就是 你先用,后面在声明
- 可不可以把 interface 写后面——你有病吗?
- 可以写在后面,但是建议写前面