# 接口
在程序设计里面,接口起到一种限制和规范作用,接口定义了某一批类所需的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这些类 里必须提供某些方法,提供这些方法的类就可以满足实际需要。
就是用接口来约束某种数据 默认不能少属性也不能多属性
接口类型:
- 属性接口
- 函数接口
- 可索引接口
- 类类型接口
- 接口扩展
# 属性接口/对象约束
比如传入一个对象,里面的属性必须进行类型约束,我们可以用接口来代替。
重名的接口会自动聚合,两个里面的属性都会进行约束。
// 批量约束,其他函数同样可以使用
interface FullName {
firstName: string;
lastName: string
}
// 传入的name参数实现FullName约束
function printName(name: FullName):void {
console.log(name.firstName +'----'+name.lastName)
}
let obj = {
firstName: 'chang',
lastName: 'zhen'
}
printName(obj);
# 可选属性与readonly
和可选参数相似,使用 ?
来定义,可传可不传。readonly定义只读属性,表示对象的这个属性定义后不能被修改。
// 可选属性
interface chooseName{
firstName?: string;
lastName: string
}
function getName(name: chooseName) {
console.log(name)
}
getName({
firstName: 'zhang',
lastName: 'san'
})
getName({ // 可以不传
lastName: 'chang'
})
// 只读属性
interface userInfo{
readonly id: string;
name: string
}
const obj:userInfo = {
id: 1,
name: 'xxx'
}
# 函数类型接口
对方法传入的参数以及返回值进行约束
interface encrypt {
// 函数的参数类型及返回类型
(key: string, value: string):string;
}
// 方法里的参数名不需要与接口定义的名相同,但类型要一样
let md5:encrypt = function(keyText:string, valueText:string):string {
return keyText +'-----'+ valueText
}
console.log(md5('md5header', 'md5footer'))
let sha1:encrypt= function(key:string, value:string):string {
return key+'----'+value
}
console.log(sha1('sha1header', 'sha1footer'))
# 数组类型接口
普通类型数组是在后面加 string[]
,接口数组也是一样 interface[]
// 普通类型数组
let arr1:number[] = [2, 2, 1, 44, 5]
// 约束对象数组
interface userArr {
name:string
}
// 其元素必须满足userArr为一个有name的对象
let arr:userArr[] = [{name: '111'}, {name: '222'}]
# 可索引接口
如果只对数组或对象中的某几个属性进行约束,但是不想全部属性都进行约束,其他的属性我们就可以使用索引接口在[]
中不进行约束。
// 数组约束接口
// 对数组的为为数字类型的下标都约束为字符串
interface userArr {
[index:number]:string
}
let arr:userArr=['str', 'hahah']
console.log(arr)
// 对对象中其他为字符串的属性约束为任意类型
interface userObj {
name: string;
age: number;
[propName: string]: any;
}
let object:userObj = {
name: 'chang',
age: 18,
grade: 100,
class: 1
}
console.log(object)
# 类类型接口
对类的约束,使用implements
关键字来定义
interface Animal {
name: string
eat(str?:string):void
}
// 类必须要有name和eat
class Dog implements Animal {
name:string
constructor(name:string) {
this.name = name
}
eat(food?:string):void {
console.log(`${this.name}eat ${food}`)
}
}
var dog = new Dog('小猫')
dog.eat('老鼠');
# 把类当做接口
class A {
type: boolean = false
changeType() {
this.type = !this.type
}
}
class B {
name:string = 'xxx'
getName():string {
return this.name
}
}
class C implements A,B {
type: boolean = true
name:string = '123'
getName():string {
return this.name
}
changeType() {
this.type = !this.type
}
}
# 接口继承
接口可以继承接口
interface Person {
eat(food:string):void;
}
interface Web extends Person {
work():void;
}
// 必须要实现所有的方法
class Web1 implements Web {
name:string
constructor(name:string) {
this.name = name
}
eat(food:string) {
console.log(`${this.name}eat${food}`)
}
work() {
console.log(`${this.name}工作中`)
}
}
var w = new Web1('小常');
w.eat('苹果');
w.work();
// 父类
class Programmer {
name:string
constructor(name:string) {
this.name = name
}
coding():void {
console.log(`${this.name}写代码`)
}
}
// 即继承父类又继承接口
class Web2 extends Programmer implements Web {
constructor(name:string) {
super(name)
}
eat(food:string) {
console.log(`${this.name}eat${food}`)
}
work() {
console.log(`${this.name}工作中`)
}
}
let w2 = new Web2('小李')
w2.coding();