抽象类别和介面 (2)

什麽是抽象类别

an abstract class, or abstract base class (ABC), is a class that cannot be instantiated because it is either labeled as abstract or it simply specifies abstract methods (or virtual methods). An abstract class may provide implementations of some methods, and may also specify virtual methods via signatures that are to be implemented by direct or indirect descendants of the abstract class.

抽象类别是一种无法建立实例的类别。抽象类别可以提供方法(可以有、或没有实作细节)给 child 类别使用,另一方面,child 类别需要能够实现所继承的抽象类别的所有方法。

在上一篇文章的例子当中,我们并没有在 Athlete 当中提供 hit 方法的实作细节,但实际上我们也可以提供,像是下面这样

abstract class Athlete {
  name: string

  constructor(name: string) {
    this.name = name
  }

  hit() {
    console.log(`${this.name} can hit`)
  };
}

接着,让 BaseballPlayer 直接沿用 Athletehit 方法,而让 TennisPlayer 用自已定义的 hit 方法来覆写原本的 hit 方法:

class BaseballPlayer extends Athlete {
  pitch() {
    console.log(`${this.name} can pitch the ball`)
  }
}

class TennisPlayer extends Athlete {
  hit() {
    console.log(`${this.name} can hit tennis`)
  }
  serve() {
    console.log(`${this.name} can serve`)
  }
}

得到结果

const jeter = new BaseballPlayer('jeter')
const federer = new TennisPlayer('federer')

jeter.hit()           // jeter can hit
federer.hit()         // federer can hit tennis

什麽是介面

an interface is a shared boundary across which two or more separate components of a computer system exchange information.

广义来说,介面是两个实体交换资讯的边界,在这个边界上,资讯格式会被定义(规范),好让两个实体能够顺利交换资讯。

In some object-oriented languages, especially those without full multiple inheritance, the term interface is used to define an abstract type that contains no data but defines behaviours as method signatures.
...
An interface is thus a type definition; anywhere an object can be exchanged (for example, in a function or method call) the type of the object to be exchanged can be defined in terms of one of its implemented interfaces or base-classes rather than specifying the specific class.

而在一些物件导向程序语言当中,介面就像是抽象类别一种,定义了行为但不包含任何资料。
...一个介面因此就是一个型别 (type) 的定义,在任何可以交换物件的地方,要被交换的物件的类型,可以由介面来定义,而不是它的类别 (class)。

上面的解释其实有点抽象和复杂,举一个现实生活中的例子的话,我们每天都在使用的「插座的形状」,其实就是一种介面,它定义了两个实体 (输电线的插座、电器的插头) 互动的格式,但不参与他们实现的方式。实际上实现的是主体是

  • 插座的制造商。他们根据这个形状,做出同样形状的插座
  • 电器的制造商。他们根据这个形状,做出同样形状的插头

所以有了介面,电器的制造商不需要管谁是插座的制造商,因为不管是谁来生产插座,都会是一样的形状。反之亦然。

在物件导向程序设计当中,介面的意义就是,当我们只要定义好一个交换 (或互动) 的格式,那麽我们就可以完全不需要去管究竟是哪个类别的物件要来进行资料交换或互动。

以先前的例子来说,就是有任何的类别执行 (implement) Hit 这个介面的话,就可以百分之百保证这个类别有一个 hit 方法可以呼叫!

class XXXX implements Hit {
  ...
}

关於型别 (type)

另一方面,在 TypeScript 当中,我们可以定义一个方法当中「输入」和「输出」的型别 (type)。譬如以下面的例子来说,这里有一个可以获得棒球选手报告的 getReport,当我们传入全垒打的数量,就可以获得一行报告。

在这个方法当中,我们定义了输入资料 homeRuns 的型别为数字,输入资料为字串,但是没有定义最後输出的字串长什麽样子

interface GetReport {
  getHomerunReport(homeRuns: number): string;
}

接着,我们让 BaseballPlayer 来执行介面 GetReport,并实际定义 getHomerunReport 的细部内容

class BaseballPlayer implements GetReport {
  name: string

  constructor(name: string) {
    this.name = name
  }

  getHomerunReport(homeRuns: number): string {
    return `${this.name} has ${homeRuns} homeruns this season!`
  }
}

最後,我们就可以呼叫 getHomerunReport,传入一个数字,得到一个字串

const jeter = new BaseballPlayer('jeter')
jeter.getHomerunReport(20)  // jeter hit 20 homeruns this season!

虽然在 TypeScript 当中型别和介面看起来是不一样的东西,但实际上当我们在定义型别的时候,就是在定义广义上的介面。

抽象类别和介面的差别

相较於建立一个 parent 类别,抽象类别和介面带来了更多的弹性,可以在定义一个类别所需要属性或方法时,也让类别拥有自己实作的方式。

抽象类别和介面两者看起来很相似,不过还是有差异,像是

  • 抽象类别本身其实也可以定义实作方式,当一个类别继承抽象类别之後之後,可以决定是否要继续采用,或是覆写成自己的实作方式。而介面是完全无法定义实作方式
  • 一个类别只能继承一个抽象类别,但是可以执行多个介面,像是
class BaseballPlayer implements Hit, Run, Jump {
  ...
}

使用抽象类别时,它和 child 类别本身还是有「A 是 B 的一种」的关系,以刚刚的例子来说,就是BaseballPlayerAthlete 的一种。因此跟先前提到的 parent 类别一样,抽象类别和一般类别需要建立在有逻辑的阶层关系上,才不会造成未来实作上的混乱和错误。

而建立介面的时候,就不太需要在乎和类别之间的关系,只要关心自己需要定义什麽互动的格式就行了!


<<:  AI ninja project [day 20] object detection

>>:  新新新手阅读 Angular 文件 - ngFor(2) - Day20

javascript变数与运算子2

接下来介绍各种运算子,也是用程序码跟注解做说明 以下是执行程序 ...

[Day30] 第三十课 Azure学习建议与深入浅出Azure常用服务小结

终於来到第30天了,每天写下来不知不觉就一个月了,记得第一课还在自我介绍, 转眼间已经要第三十课。这...

Day 07 : 资料视觉化 Matplotlib

昨天介绍的资料分析後,相信大家对於资料分析都能轻松上手。把特如果要把一堆数据和资料给你的老板和顾客看...

Day 16-制作购物车系统之backend

今天要来说後端的部分 以下内容有参考教学影片,底下有附网址。 (内容包括我的不专业解说分析及在实作过...