TypeScript笔记 6--接口

时间:2022-12-22 16:02:27

接口定义

接口和Java语言一样,都是通过关键字interface定义的,如下例子:

interface People {
name: string;
age: number;
hobby?: string; // 可选属性
readonly sex: string; // 只读属性
run: (steps: number) => void; // 箭头函数
play():void; // 普通函数
}

接口使用

function test(people:People) {
// content
people.sex = 'xxx'; // 编译器报错
}

let p = {
age: 1, name: 'z', sex: 'x',
run: (s: number) => {
return 1;
},
play:function() {

},
height:180

}
demo(p);

如上例子,当前对象p作为参数传入函数test中时,编译器只会检查那些必需的属性(函数也是一种属性)是否存在,类型是否匹配,如果缺少必要的属性,编译器会报错。至于多出的属性height,编译器则不会检查,这点我们可以这样理解:对象pPeople的实现,也就是其子类。height是子类中的属性,这样的话很容易理解。

可选属性

接口里的属性不全都是必需的。属性名后面加上?表示是一个可选属性。

有些是只在某些条件下存在,或者根本不存在.如上述例子中hobby属性,我们在构造p对象时就算没有传入hobby属性,编译器不会报错。

只读属性

只读属性用readonly修饰,一旦该属性赋值后,就不能再修改了,否则编译器报错。

前几章中学习了常量const,它们没有什么差别,最简单判断该用readonly还是const的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用 const,若做为属性则使用readonly。

函数

关于函数的声明有两种,箭头函数和普通方式。在上面的例子中,我们声明了两个函数runplay,虽然生命方法不一样,但是使用方法是一样的,只是作用域不一样,究竟有什么不一样,以后再讲。

接口实现和继承

类可以实现接口,接口也可以继承接口并且只能描述公有属性,这些都是和Java是一样的。

class Player implements People {
name: string;
age: number;
readonly sex: string; // 只读属性

constructor() {
}

run= (steps: number) => {

} // 箭头函数

play():number {

return 100;
}
}

interface Player extends People {
item:string;
}

接口继承类,多继承

在Java中接口只能继承接口,而且只能继承一个接口,但是ts中的接口可以继承类,同时支持多继承。接口继承只能继承类中的属性和函数(不继承其实现)。父类中的私有属性和受保护属性也能继承,但是如果这样的继承的话,这个接口类型只能被这个类或其子类所实现。

class Animal {
name: string;
private age: string;

run(): void {
console.log('running...');
}
}

interface Person extends Animal {}

function eat(p: Person) {}

let p = { name: '', age: 'x', sayHello: function () { return '' } };
eat(p); // 编译报错

上述代码会报错,因为age是私有属性,而对象p中age是公有的,这样会产生冲突。所以接口Person必须是Animal的子类所实现。

要想编译不报错,有两种方法:第一是将age属性改为公有,第二种是新增一个类,该类是Animal子类, 如下:

class Animal {
name: string;
private age: string;

run(): void {
console.log('running...');
}
}
interface Person extends Animal {
say(): void;
}
class Child extends Animal {
say(): void {
}
}
function eat(p: Person) { }
let p = new Child();
eat(p);// 这样不会报错