TypeScript面向对象
TypeScript面向对象
面向对象是程序中一个非常重要的思想。面向对象很简单,简而言之就是程序之中所有的操作都需要通过对象来完成。一切皆对象
接口
TypeScript中的接口跟传统语言(比如Java)的接口有点差别
对象可以隐式实现接口
概念
描述一个类型
一个接口里面可以有:
- 字段
- 方法
- 可选字段以及方法
- 只读字段
用法
- 可选字段串联
interface Employee{
name?:{
first?:string
last: string
}
// 只读字段
readonly addr: string
}
function hasBadName(emp: Employee){
// 可选字段使用?来串联,防止报错
return emp.name?.first?.startsWith("A")
}
- 非空断言
function hasBadName(emp: Employee){
// 使用!来串联字段,表示为非空,但是如果真的是空就会报错
return emp.name!.first!.startsWith("A")
}
- 接口的扩展
interface HasName{
name?:{
first?:string
last: string
}
}
// 使用extends关键字类扩展接口
interface Employee extends HasName{
salary:number
bonus?:number
}
- 类型的并
- 类型断言
- 类型判断
// 定义2个接口
interface MyButton{
visible: boolean
enabled: boolean
onClick(): void
}
interface MyImage{
visible: boolean
src: string
width: number
height: number
}
// 方法参数是 类型的并
function processElement(e: MyButton | MyImage){
// 类型判断
if((e as any).onClick){
// 类型断言
const btn = e as MyButton
btn.onClick()
}else{
const img = e as MyImage
console.log(img.src)
}
}
// 我们还可以简化上面的方法
// 通过这样定义一个方法来判断是否是某接口类型, 返回值类型是boolean, 可以写成e is MyButton
// 这种语法有点奇怪,但是也好理解,就是我们的返回结果是否是MyButton类型
function isButton(e: MyButton | MyImage): e is MyButton{
return (e as MyButton).onClick !== undefined
}
// 简化上面的方法
function processElement2(e: MyButton | MyImage){
// 类型判断,由于上面的e is MyButton的语法,这里就不需要 as 的这种语法了:const btn = e as MyButton
if(isButton(e)){
e.onClick()
}else{
console.log(e.src)
}
}
接口实现
- 对象可以隐式实现接口
类
- 类的定义
- 构造函数
- private/public的属性
- 方法
- getter/setter方法
- 类的继承
用法如下
class Employee {
private _bonus?: number
// 写在对象里面的属性
addr?: string
// 通过构造器的参数来描述属性
// 在对象里面写的属性或者构造器的属性都可以说明访问权限 public或private
constructor(public name: string, private salary: number){}
// setter/getter 方法
set bonus(v:number){
this._bonus = v
}
get bonus(){
return this._bonus || 0
}
// 对象里面的方法
updateSalary(){
// do something
}
}
// 类的继承
class Manager extends Employee {
private reporters: Employee[] = []
constructor(name: string, salary: number){
super(name, salary)
}
addReporter(emp: Employee){
this.reporters.push(emp)
}
}
// 使用类
const emp = new Employee("a", 100)
emp.addr = "北京"
emp.bonus = 10000
console.log(emp)
const manager = new Manager("b", 200)
console.log(manager)
使用类来实现接口
- 隐式实现
TypeScript中隐式实现接口,接口与实现类之间的耦合非常低
TypeScript是通过对比类与接口的属性,方法,全部包含这个接口中的就实现了这接口
// 定义一个接口
interface IEmp{
name:string
salary:number
bonus?:number
addr?:string
}
// 那么上面的Employee、Manager 就实现了这个接口
const emp: IEmp = new Employee("a", 100)
const manager: IEmp = new Manager("b", 200)
- 显示实现接口
class EmployeeImpl implements IEmp {
// ...
}
- 定义者=使用者 隐式实现 (推荐)go语言也是这么做的
- 定义者=实现者 显示实现 传统的编程语言都是这样,比如Java
- 在实际中接口应该是使用者来定义才更符合我们的习惯,因为使用者才知道我需要接口给我提供什么能力
泛型
主要用来约束方法参数,类似java的泛型
基本使用
// 泛型约束数组中的元素类型
const arr: Array<number> = []
arr.push(1)
// 泛型约束Promise的返回值类型
new Promise<string>((resolve, reject) => {
return resolve("ok")
})
使用泛型定义方法与对象
class MyArray<T> {
data: T[] = []
add(t: T) {
this.data.push(t)
}
map<U>(fun: (t: T) => U): U[] {
return this.data.map(fun)
}
print() {
console.log(this.data)
}
}
泛型的限定
interface HasName {
name: string
}
// 限定泛型必须实现此接口,泛型元素就可以使用此接口的元素或者方法了
class MyArray<T extends HasName> {
data: T[] = []
add(t: T) {
this.data.push(t)
}
map<U>(fun: (t: T) => U): U[] {
return this.data.map(fun)
}
getAllName(): string[] {
return this.data.map(v => v.name)
}
print() {
console.log(this.data)
}
}
分类:
前端
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)