跳转到内容

类的多态

刀刀
0字
0分钟
2026/8/16

含义

多态是在父类中定义的属性和方法被子类继承后,可以有不同的实现。

使用场景

一个 H5 项目,允许钉钉登录,也允许微信登录,二者的登录业务逻辑不同,这里就需要使用到多态,做不同的逻辑处理。

实现

父类

先写一个父类,实现登录功能,调用一个 getUserInfo() 方法获取用户信息,然后调用 login 方法实现登录逻辑。getUserInfo() 方法在父类中不实现,由子类去实现。简要代码如下所示:

父类.ts
ts
function login(phone) {
  return `${phone} 登录成功`
}

class BaseLogin {
  abstract getUserInfo(): Promise<{ phone: string }>
  async login() {
    const { phone } = await this.getUserInfo()
    const token = await login(phone)
    this.afterLogin(token)
  }
  private afterLogin(token) {
    console.log('登录成功:', token)
  }
}

子类

接下来实现两个子类,各自实现各自的 getUSerInfo 功能,分别实现钉钉登录和微信登录。钉钉登录需要调用钉钉的 API,微信登录需要调用微信的 API,这里只是简单模拟一下,实际项目中需要调用对应的 API。简要代码如下所示:

子类.ts
ts
function login(phone) {
  return `${phone} 登录成功`
}

class BaseLogin {
  abstract getUserInfo(): Promise<{ phone: string }>
  async login() {
    const { phone } = await this.getUserInfo()
    const token = await login(phone)
    this.afterLogin(token)
  }
  private afterLogin(token) {
    console.log('登录成功:', token)
  }
}

class DingTalkLogin extends BaseLogin {
  async getUserInfo() {
    console.log('获取丁丁信息') 
    await new Promise((resolve) => setTimeout(resolve, 1000)) 
    return { phone: 'dingding' } 
  } 
} 

class WeChatLogin extends BaseLogin {
  async getUserInfo() {
    console.log('获取微信信息') 
    await new Promise((resolve) => setTimeout(resolve, 1000)) 
    return { phone: 'wechat' } 
  } 
} 
const loginMap = {
  dingTalk: DingTalkLogin, 
  wechat: WeChatLogin, 
} 

function loginFactory(type: 'dingTalk' | 'wechat') {
  return new loginMap[type]() 
} 
loginFactory('dingTalk').login() 
loginFactory('wechat').login() 

严谨

每个类只支持外部调用它们的 login 方法,而不允许外部直接调用 getUserInfo 方法。

ts
function login(phone) {
  return `${phone} 登录成功`
}

class BaseLogin {
  protected abstract getUserInfo(): Promise<{ phone: string }>
  async login() {
    const { phone } = await this.getUserInfo()
    const token = await login(phone)
    this.afterLogin(token)
  }
  private afterLogin(token) {
    console.log('登录成功:', token)
  }
}

class DingTalkLogin extends BaseLogin {
  protected async getUserInfo() {
    console.log('获取丁丁信息')
    await new Promise((resolve) => setTimeout(resolve, 1000))
    return { phone: 'dingding' }
  }
}

class WeChatLogin extends BaseLogin {
  protected async getUserInfo() {
    console.log('获取微信信息')
    await new Promise((resolve) => setTimeout(resolve, 1000))
    return { phone: 'wechat' }
  }
}
const loginMap = {
  dingTalk: DingTalkLogin,
  wechat: WeChatLogin,
}

function loginFactory(type: 'dingTalk' | 'wechat') {
  return new loginMap[type]()
}
loginFactory('dingTalk').login()
loginFactory('wechat').login()

贡献者

The avatar of contributor named as duyidao duyidao
The avatar of contributor named as 刀刀 刀刀

页面历史

刀刀博客累计访客 人;文档累计访问量共