一.对interface的理解
1. 接口:定义和规范行为动作标准,不关心这些行为动作标准的具体实现,只要满足标准就可以
2. 接口中的方法都是抽象方法(无需使用abstract声明),且没有具体实现
3. 接口类型:属性类型接口 函数类型接口 类类型接口 可索引类型接口...以及接口扩展
4. 接口属性与方法之间可以用逗号(,)或者分号(;)分隔,或者什么也不用
二.接口与抽象类的比较
1. 不同类之间的共有属性/方法,可以抽象成一个接口
2. 抽象类是供其他类继承的基类,不能被实例化,抽象类中的抽象方法/属性必须在子类中实现/初始化
3. 接口是一种标准描述,接口中的属性/方法必须在使用接口时初始化和实现
4. 抽象类本质是一个不能被实例化的类,但是内部能够实现方法与初始化属性
5. 接口只用于描述规范,不能实现方法与初始化属性
6. 一个类只能继承一个父类/抽象类,但能使用多个接口
7.抽象类也可以使用接口
interface Actions {
speak():any
eat():any
}
interface Hobbies {
music:string[]
movies:string[]
}
//一个类可以有多个接口,接口之间用逗号(,)分隔
class Person implements Actions , Hobbies {
speak() {
console.log(this.music);
}
eat() {
console.log(this.foods);
}
foods = ['水果','牛奶']
music = []
movies = []
}
let p = new Person
p.eat()
//抽象类使用接口
abstract class Animal implements Actions {
eat() {
console.log('它吃'+this.foods);
}
speak() {
console.log('它说'+this.utterance);
}
abstract actions():any
utterance:string
foods:string[]
constructor(utterance:string,foods:string[]) {
this.utterance = utterance
this.foods = foods
}
}
class Dog extends Animal {
constructor(utterance:string,foods:string[]) {
super(utterance,foods)
}
actions() {
this.eat()
this.speak()
}
}
let dog = new Dog('汪汪',['骨头'])
dog.eat()
dog.speak()
//子类继承抽象类并实现接口
class People extends Animal implements Hobbies {
music = []
movies = []
actions() {}
}
let people = new People('你好',['鲁菜','粤菜'])
console.log(people);
三.接口的一些属性与类型
namespace one {
//1.任意属性
interface PlainObject {
[propName:string]:number|string,
}
let obj:PlainObject = {
x:1,
y:2,
z:'apple'
}
//2.接口的继承,接口可以继承多个接口,如果使用的接口有父接口,那么也必须实现父接口的方法和属性
interface Actions {
speak():any
}
interface Play extends Actions{
flying():any
}
class People implements Play{
speak() {}
flying() {
}
}
//3.接口的只读属性readonly
interface Circle {
readonly pi:3.14
radius:number
}
let circle:Circle = {
pi:3.14,
radius:50
}
//circle.pi = 3 只读属性不能修改
//4.函数类型接口
interface Discount {
(price:number,count:number,discount:number):number
}
let discountGoods:Discount =(price:number,count:number,discount:number):number=>{
return price*count*discount
}
discountGoods(10,21,0.2)
//5.可索引接口,用来约束数组和对象
interface Indexable {
[index:number]:string|number|object
}
let arr:Indexable = [1,'2']
let o:Indexable = {
1:1,
2:'apple',
3:[1,2,3]
}
//6.类的接口
//-6.1 规定行为
interface Behavior {
greet():any
eat():void
}
class Animal implements Behavior {
greet() {}
eat() {}
speak() {}
flying(){}
}
//-6.2规定构造函数类型,使用new 来规定
interface AnimalCategory {
new(category:string):People
}
function getAnimalCategory(constructorType:AnimalCategory,name:string) {
return new constructorType(name)
}
let animal = getAnimalCategory(Animal,'cat')//Animal必须符合接口AnimalCategory规定的构造函数People,People中有speak和flying两个方法,那么Animal必须也要有
console.log(animal);
//7.接口的兼容性 接口与接口可以兼容,接口与class也可以兼容
interface StrType {
name:string
age:number
toUpperCase:()=>string
}
interface numType {
age:number
name:string
toUpperCase:()=>string
speak:()=>any
}
class PType {
name:string
age:number
constructor(name:string,age:number) {
this.name = name
this.age = age
}
toUpperCase(){
return this.name.toUpperCase()
}
speak() {
}
action() {}
}
function getName(p:StrType):string {
return p.toUpperCase()
}
let p = {
name:'apple',
age:10,
toUpperCase:function ():string {
return p.name.toUpperCase()
}
}
let s:numType = {
age:20,
name:'pear',
toUpperCase(){
return s.name.toUpperCase()
},
speak() {
}
}
let pp = new PType('orange',100)
/* console.log(getName(p)); */
console.log(getName(s)); //s:numType使用numType接口,getName参数类型要求StrType接口,numType接口的属性符合StrType接口的规定,所以也可以传参s
console.log(getName(pp))
}