typescript:5、接口、类

1、typescript接口

1、typescript接口概念

用于描述一个类型
在这里插入图片描述

1.2、typescript语法

定义接口

interface Employee {
	readonly name: string //只读字段,定义值之后不能更改
	salary: number
	bonus?: number //可选字段
}

const emp1: Employee = {
	name: 'john',
	salary: 8000,
}

可选字段串联/非空断言

interface Employee {
	name? : {
		first?: string
		last: strign
	}
	salary: number
	bonus?: number
}
//返回boolean或undefined
function hasBadName(e: Empoyee){
	//可选字段串联用法
	return e.name?.first?.startsWith('AAA')
	
	//非空断言用法
	//下方的!表示的是告诉编译器e.name一定有值,不需要去管,后果自负
	//return e.name!.first!.startsWith('AAA')
}
hasBadName({
	name: {
		last: 'smith',
	},
	salary: 8000
})

接口扩展

interface HasName {
	name?: {
		first?: string
		last: string
	}
}
//使用extends之后,Employee就有name字段了
interface Employee extends HasName{
	salary: number
	bonus?: number
}

类型的并和类型断言

interface WxButton {
	visible: boolean
	enabled: boolean
	onClick(): void
}
interface WxImage {
	visiable: boolean
	src: string,
	width: number
	height: number
}
//processElement(e: WxButton | WxImage),此时的e的类型是WxButton和WxImage并出来的
function processElement(e: WxButton | WxImage){
	if(isButton(e)) {
		e.onClick()
	}else{
		console.log(e.src)
	}
}
/*
processElement函数的普通写法
function processElement(e: WxButton | WxImage) {
	if( (e as any).onClick){
		const btn = e as WxButton
		btn.onClick()
	}else{
		const img = e as WxImage
		console.log(img.src)
	}
}
*/
//类型判断
function isButton(e: WxButton | WxImage): e is WxButton {
	//e as WxButton为类型断言
	return (e as WxButton).onClick !== undefined
}
processElement({
	visiable: true,
	enabled: true,
	onClick(){
		console.log('clicked')
	}
})

2、类

class Employee {
	name: string = '' //1、类属性定义后一定要初始化值
	salary: number //2、若属性没有在定义时初始化,那么可以在构造函数中赋值
	private bonus: number = 0
	//3、构造函数
	constructor(salary: number) {
		this.salary = salary
	}
	
	updateSalary(){}
}
const emp1 = new Employee(8000)
//所有的属性和方法默认都是public的,外面都可以调用
emp1.updateSalary()
emp1.name

属性简易定义的方法

class Employee{
	//可选字段
	private bonus?: number
	//在构造方法中的参数添加public关键字
	//相当于定义了字段,并赋值
	constructor (public name: string, public salary: number) {}
	/*
	//上方的未注释的构造函数与下方代码等价
	name: string
	salary: number
	constructor(name: string, salary: number){
		this.name = name
		this.salary = salary
	}
	*/
}

getter/setter

class Employee{
	private allocatedBonus?: number
	//setter
	set bonus(v: number) {
		this.allocatedBonus = v
	}
	//getter
	get bonus(){
		return this.allocatedBonus || 0
	}
}
const emp1 = new Employee()
emp1.bonus = 20000 //使用setter,跟属性的用法一样
console.log(emp1.bonus)

继承

class Employee{
	private allocatedBonus?: number
	constructor(public name: string, public salary: number){}
	set bonus(v: number){
		this.allocatedBonus = v
	}
	get bonus(){
		return this.allocatedBonus || 0
	}
}
class Manager extends Employee{
	private reporters: Employee[]
	constructor (name: string, salary: number){
		super( name, salary)
		this.reporters = []
	}
	addReporter(e: Employee){
		this.reporters.push(e)
	}
}
const emp1 = new Employee('john', 8000)
emp1.bonus = 20000
const manager1 = new Manager('mary', 18000)
manager1.addReporter(emp1)
manager1.bonus = 50000
console.log(manager1)

3、用类来实现接口

3.1、隐式实现

 //定义接口
interface Service {
	login():void
}
//实现接口(隐式实现)
class PRCService{
	login(): void {
		//do something
	}
}
//file: login.ts
// 使用接口
const page = {
	service: new PRCService() as Service,
	onLoginButtonClicked(){
		//使用接口
		this.service.login()
	}
}

3.2、显式实现

下方会导致接口特别大(里面的方法特别多),所以不是特别推荐

//定义接口 
//file: service.ts
interface Service {
	login(): void
	getTrips(): string
	getLic(): string
	startTrip(): void
	updateLic(lic: string): void
}
//实现接口
//file: service.ts
class PRCService implements Service {
	login(): void {
		throw new Error("Method not implemented.");
	}
	getTrips(): string {
		throw new Error("Method not implemented.");
	}
	getLic(): string {
		throw new Error("Method not implemented.");
	}
	startTrip(): void {
		throw new Error("Method not implemented.");
	}
	updateLic(lic: string): void {
		throw new Error("Method not implemented.");
	}
}

// 使用接口
//file: login.ts
const page = {
	service: new PRCService() as Service,
	onLoginButtonClicked(){
		//使用接口
		this.service.login()
	}
}

3.3、如何选择显式实现和隐式实现

如果一个接口过大,方法特别多,这样并不是很推荐。一般都建议使用隐式实现接口,可以让接口的方法少一些

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值