TypeScript(四)類與接口

類實(shí)現(xiàn)接口

類類型接口是類遵循的某種約束和規(guī)則尺借。

類可以通過關(guān)鍵字 implements 實(shí)現(xiàn)接口。

interface IPerson {
  name: string;
  eat(): void
}

class Person implements IPerson {
  // 如果構(gòu)造函數(shù)參數(shù)中顯式設(shè)置屬性的訪問控制符為public怎憋,則會(huì)默認(rèn)初始化該屬性
  constructor(public name: string) {}
  eat(): void {
    console.log( `${this.name} 吃飯` )
  }
}

const p1 = new Person('mike')
console.log(p1)

此外通過上文可知屿衅,一個(gè)類只能繼承另一個(gè)類,但有時(shí)不同類之間卻有一些共同的特性擅腰,這時(shí)可以把共有特性提取成接口蟋恬,使用類去實(shí)現(xiàn)。

列舉網(wǎng)上的一個(gè)案例:門是一個(gè)類趁冈,防盜門是門的子類歼争。如果防盜門有一個(gè)報(bào)警器的功能,我們可以給防盜門添加一個(gè)報(bào)警方法渗勘。這時(shí)候如果有另一個(gè)類沐绒,車,也有報(bào)警器的功能旺坠,就可以考慮把報(bào)警器提取出來乔遮,作為一個(gè)接口,防盜門和車都去實(shí)現(xiàn)它:

interface Alarm {
  alarm(): void
}

class Door { }

class SecurityDoor extends Door implements Alarm {
  alarm() {
    console.log('SecurityDoor alarm')
  }
}

class Car implements Alarm {
  alarm() {
    console.log('Car alarm')
  }
}

一個(gè)類可以同時(shí)實(shí)現(xiàn)多個(gè)接口:

interface IPerson {
  name: string;
  eat(): void;
}

interface IPersonX {
  age: number;
  skill(): string;
}

class PersonX implements IPerson, IPersonX {
  name: string
  age: number
  constructor(name: string, age: number) { 
    this.name = name
    this.age = age
  }
  eat(): void {
    console.log( `${this.name} 吃飯` )
  }
  skill(): string {
    return `${this.name} age is ${this.age} sleep` 
  }
}

const p2 = new PersonX('nike', 12)

類的靜態(tài)部分和實(shí)例部分

關(guān)于類需要明確的一點(diǎn)是取刃,類有兩部分蹋肮,靜態(tài)部分和實(shí)例部分。

通過以上方式定義的接口只會(huì)檢查類實(shí)例的屬性璧疗,對(duì)于類靜態(tài)屬性的檢查需要單獨(dú)定義接口坯辩。

首先通過下面例子思考一個(gè)問題:

interface PersonInterface {
  name: string
  age: number
  eat(): void
}

const person: PersonInterface = {
  name: 'mike',
  age: 12,
  eat() {
    console.log('food')
  }
}

class Person implements PersonInterface {
  name: string
  age: number
  constructor() {}
  eat() {
    console.log('food')
  }
}

接口PersonInterface很明顯是一個(gè)對(duì)象類型的接口,為什么類實(shí)現(xiàn)接口時(shí)崩侠,類中存在constructor方法確不報(bào)錯(cuò)漆魔?那么類實(shí)現(xiàn)的接口究竟是對(duì)誰(shuí)的約束?

事實(shí)上類實(shí)現(xiàn)的接口只是對(duì)類實(shí)例出來的對(duì)象的約束却音,只會(huì)對(duì)其實(shí)例屬性進(jìn)行檢查改抡。而TS中constructor方法則屬于類的靜態(tài)方法,即屬于類的靜態(tài)部分僧家,對(duì)靜態(tài)屬性的約束需要額外定義接口雀摘。

TS中類的靜態(tài)部分指的是這個(gè)類本身;
實(shí)例部分指的是類實(shí)例化出來的對(duì)象八拱;

所以對(duì)類約束的接口需要通過以下方式定義:

interface IDogInterface {
  new (name: string, age: number)
  getName(): void
}

const Dog: IDogInterface = class {
  name: string
  age: number
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  static getName() {
    console.log('dog')
  }
}

再看下面例子:

interface PersonInterface {
  name: string
  age: number
  eat(): void
}

class Person implements PersonInterface {
  name: string
  age: number
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  eat() {
    console.log('food')
  }
}

const person = new Person(33, 'mike')

以上類Person實(shí)現(xiàn)接口PersonInterface阵赠,在類中我們定義了兩個(gè)公有屬性name、age肌稻,并對(duì)其類型進(jìn)行了約束清蚀,注意:只是給類實(shí)例定義了兩個(gè)屬性name、age爹谭。
創(chuàng)建實(shí)例時(shí)枷邪,調(diào)用構(gòu)造方法constructor,該函數(shù)接收的兩個(gè)參數(shù)的類型是實(shí)際上是any類型诺凡,和公有屬性name东揣、age沒有關(guān)系践惑。創(chuàng)建實(shí)例的過程和js是一致的(首先創(chuàng)建一個(gè)對(duì)象,然后初始化該對(duì)象嘶卧,再然后賦值給this尔觉,最后返回this)。

但是如果通過實(shí)例修改name的值芥吟,如果類型不一致則會(huì)報(bào)錯(cuò)侦铜。

person.name = 22 // Type '22' is not assignable to type 'string'

由此可以看出類實(shí)現(xiàn)的接口僅僅是對(duì)類實(shí)例的約束。

所以對(duì)一個(gè)類的實(shí)例部分和靜態(tài)部分的約束需要定義兩個(gè)接口钟鸵,一個(gè)用來檢查靜態(tài)部分钉稍,一個(gè)用來檢查實(shí)例部分。

// PersonConstructor 用來檢查靜態(tài)部分的
interface PersonConstructor {
  new (name: string, age: number): PersonInterface // 檢查 constructor 并且創(chuàng)建的類必須是通過PersonInterface接口實(shí)現(xiàn)的
  typename: string              // 檢查靜態(tài)屬性 typename 
  logname(): void               // 檢查靜態(tài)方法 logname 
}
// PersonInterface 用來檢查實(shí)例部分的
interface PersonInterface {
  // new (name: string, age: number) // 靜態(tài)方法的檢查也不能寫在這里 否則會(huì)報(bào)錯(cuò)
  log(): void                        // 定義實(shí)例方法 log
}

// 創(chuàng)建一個(gè)類棺耍,需要對(duì)類的靜態(tài)部分(類本身)和實(shí)例部分都進(jìn)行約束
const PersonClass: PersonConstructor = class implements PersonInterface {
  name: string
  age: number
  static typename = 'Person type' // 定義名為 typename 的靜態(tài)屬性
  static logname() {              // 定義名為 logname 的靜態(tài)方法
    console.log(this.typename)
  }
  constructor(name: string, age: number) { // constructor 也是靜態(tài)方法
    this.name = name
    this.age = age
  }
  log() { // log 是實(shí)例方法
    console.log(this.name, this.age)
  }
}

new (name: string, age: number): PersonInterface這里的意思是該接口對(duì)類的靜態(tài)部分進(jìn)行檢查贡未,并且我們創(chuàng)建的類必須是通過 PersonInterface接口實(shí)現(xiàn)的。

如果僅僅是這樣定義的 new (name: string, age: number)烈掠,那么滿足該接口結(jié)構(gòu)的類所實(shí)現(xiàn)的接口不會(huì)有限制羞秤。是不是有點(diǎn)繞∽蟮校看例子說話:

interface IPersonConstructor<T> {
  new (name: string, age: number): T
  getName(): void
}

interface IPersonInterfaceX {
  eat(): void
}

interface IPersonInterfaceY {
  skill(): void
}

const PersonX: IPersonConstructor<IPersonInterfaceX> = class implements IPersonInterfaceX {
  static getName() {
    console.log('jack')
  }
  name: string
  age: number
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  eat() {
    console.log('food')
  }
}
const px = new PersonX('nike', 23)
px.eat()

const PersonY: IPersonConstructor<IPersonInterfaceY> = class implements IPersonInterfaceY {
  static getName() {
    console.log('jack')
  }
  name: string
  age: number
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  skill() {
    console.log('food')
  }
}
const py = new PersonY('jack', 34)
py.skill()

以上得出:滿足接口IPersonConstructor的類,它實(shí)現(xiàn)的類可以實(shí)現(xiàn) IPersonInterfaceX 和 IPersonInterfaceY 接口俐镐。而new (name: string, age: number): PersonInterface接口結(jié)構(gòu)的類矫限,它所實(shí)現(xiàn)的接口,必須滿足PersonInterface接口佩抹。

記椎鸱纭:靜態(tài)屬性和方法的檢查、實(shí)例屬性和方法的檢查是不同的 Interface

接口繼承類

class Point {
  x: number
  y: number
}

interface Point3d extends Point {
  z: number
}

let point3d: Point3d = {x: 1, y: 2, z: 3}

接口也可以繼承多個(gè)類:

class PointX {
  x: number
}

class PointY {
  y: number
}

interface Point3d extends PointX, PointY {
  z: number
}

let point3d: Point3d = {x: 1, y: 2, z: 3}

接口繼承接口

接口可以繼承一個(gè)或多個(gè)接口棍苹。查看接口繼承以及混合類型TypeScript(二)接口

類繼承

一個(gè)類可以繼承另一個(gè)類无宿,查看TypeScript(三)類

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市枢里,隨后出現(xiàn)的幾起案子孽鸡,更是在濱河造成了極大的恐慌,老刑警劉巖栏豺,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彬碱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡奥洼,警方通過查閱死者的電腦和手機(jī)巷疼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灵奖,“玉大人嚼沿,你說我怎么就攤上這事估盘。” “怎么了骡尽?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵遣妥,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我爆阶,道長(zhǎng)燥透,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任辨图,我火速辦了婚禮班套,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘故河。我一直安慰自己吱韭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布鱼的。 她就那樣靜靜地躺著理盆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凑阶。 梳的紋絲不亂的頭發(fā)上猿规,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音宙橱,去河邊找鬼姨俩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛师郑,可吹牛的內(nèi)容都是我干的环葵。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼宝冕,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼张遭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起地梨,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤菊卷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后湿刽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體的烁,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年诈闺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了渴庆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖襟雷,靈堂內(nèi)的尸體忽然破棺而出刃滓,到底是詐尸還是另有隱情,我是刑警寧澤耸弄,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布咧虎,位于F島的核電站,受9級(jí)特大地震影響计呈,放射性物質(zhì)發(fā)生泄漏砰诵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一捌显、第九天 我趴在偏房一處隱蔽的房頂上張望茁彭。 院中可真熱鬧,春花似錦扶歪、人聲如沸理肺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)妹萨。三九已至,卻和暖如春炫欺,著一層夾襖步出監(jiān)牢的瞬間乎完,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工品洛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留囱怕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓毫别,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親典格。 傳聞我的和親對(duì)象是個(gè)殘疾皇子岛宦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348