TS學(xué)習(xí)筆記(三):類(lèi)

傳統(tǒng)的 JavaScript 程序使用函數(shù)和基于原型的繼承來(lái)創(chuàng)建可重用的組件,從 ES6 開(kāi)始,JavaScript 程序能夠使用基于類(lèi)的面向?qū)ο蟮姆绞?。使?TypeScript,你可以使用 ES6 中規(guī)定的新特性,編譯后的 JavaScript 可以在所有主流瀏覽器和平臺(tái)上運(yùn)行。

基本用法

class Person {
  public love: string;
  constructor(love: string) {
    this.love = love;
  }
  public sayLove() {
    console.log(`my love is ${this.love}`)
  }
}

繼承

在構(gòu)造器里訪問(wèn) this 的屬性之前,一定要調(diào)用 super() ,這個(gè)是 TypeScript 強(qiáng)制執(zhí)行的一條重要規(guī)則。

class Person {
  public love: string;
  constructor(love: string) {
    this.love = love;
  }
  public sayLove() {
    console.log(`my love is ${this.love}`)
  }
}

class SuperPerson extends Person {
  public name: string;
  constructor(love: string, name: string) {
    super(love);
    this.name = name;
  }
  public sayName(){
    console.log(`my name is ${this.name}`)
  }
}

let me = new SuperPerson('HTML', 'funlee');
me.sayLove()
me.sayName()

訪問(wèn)控制

public、private、protected

默認(rèn)是 public, 不再贅述,參考前面例子。

當(dāng)成員標(biāo)記為 private 時(shí),它就不能在聲明它的類(lèi)的外部訪問(wèn),用 protected 修飾的屬性依然如此。

class Person {
  private love: string; // or  prot
  constructor(love: string) {
    this.love = love;
  }
  public sayLove() {
    console.log(`my love is ${this.love}`)
  }
}

let me = new Person('TS');
me.love = 'JS'; // error

private 和 protected 有一點(diǎn)不同, protected 成員在派生類(lèi)中仍然可以訪問(wèn)。例如:

class Person {
  protected name: string; 
  constructor(name: string) {
    this.name = name;
  }
}
class Man extends Person {
  private love: string;
  constructor(name: string, love: string) {
    super(name);
    this.love = love;
  }
  public say() {
    // 如果Person 中用 private 修飾 name 則不能訪問(wèn)到 name 屬性
    console.log(`my name is ${this.name}, and my love is ${this.love}`);
  }
}
let me = new Man('funlee', 'TS');

注意:TypeScript 使用的是結(jié)構(gòu)性類(lèi)型系統(tǒng),所以當(dāng)比較兩種不同的類(lèi)型時(shí),如果所有的成員的類(lèi)型都是兼容的,那么這兩個(gè)類(lèi)型就是兼容的。如:

class A {
  prop1: string
}
class B {
  prop1: string
  prop2: string
}
let instance:A = new B() // 允許這么做,因?yàn)锳的所有成員類(lèi)型,B中都有

但是如果被比較的類(lèi)里面含有 private 和 protected 類(lèi)型成員的時(shí)候,情況就不同了,這時(shí)候需要另一個(gè)類(lèi)里也含有相應(yīng)的 private 或 protected 成員,類(lèi)型才能是兼容的,所以有:

class A {
  private prop1: string
}
class B {
  private prop2: string
}
let p1:A = new B() // 報(bào)錯(cuò)
class C extends A {

}
let p2:A = new C() // 允許這么做

readonly

可以使用 readonly 關(guān)鍵字將屬性設(shè)置為只讀的,只讀屬性必須在聲明時(shí)或構(gòu)造函數(shù)里被初始化。

class Person {
  readonly name: string;
  constructor(name: string) {
    this.name = name;
  }
}
let me = new Person('funlee');
me.name = 'new name'; // error

參數(shù)屬性

參數(shù)屬性允許同時(shí)創(chuàng)建初始化成員,可以把聲明和賦值合并至一處,如:

class Person {
  constructor(public name: string, protected love: string, readonly age: number, private weight: string) {
    this.name = name;
    this.love = love;
    this.age = age;
  }
  public sayWeight() {
    console.log(`my weight is ${this.weight}`)
  }
}
let me = new Person('funlee', 'TS', 18, '55kg');
me.sayWeight()

存取器

TypeScript 支持 getter 和 setter,但是有一點(diǎn)限制:編譯器輸出必須設(shè)為 ES5 或者更高,不支持降級(jí)到 ES3,另外,當(dāng)一個(gè)存取器只帶有 get 卻不帶有 set 時(shí),它會(huì)被自動(dòng)推斷為 readonly。

class Person {
  public _love: string;
  constructor(love: string) {
    this._love = love;
  }
  get love(): string{
    return this._love;
  }
  set love(newLove: string) {
    this._love = `error!! my love can't be chenged`;
  }
}
let me = new Person('TS');
console.log(me.love); // TS
me.love = 'HTML';
console.log(me.love); // error!! my love can't be chenged

靜態(tài)屬性

可以使用static來(lái)定義類(lèi)里的靜態(tài)屬性,靜態(tài)屬性屬于類(lèi)自身,而不屬于實(shí)例,訪問(wèn)的時(shí)候要用類(lèi)名訪問(wèn),而不能用實(shí)例對(duì)象訪問(wèn),如:

class Person {
  static love: string = 'TS';
}
let me = new Person();
console.log(Person.love); // TS
console.log(me.love); // error

抽象類(lèi)

抽象類(lèi)只能作為其他派生類(lèi)的基類(lèi)使用,抽象類(lèi)不能被實(shí)例化,它具有如下特點(diǎn):

  • 抽象類(lèi)可以包含成員的實(shí)現(xiàn)細(xì)節(jié),且抽象類(lèi)必須用 abstract 聲明
  • 抽象類(lèi)里不含方法體的方法稱(chēng)為抽象方法,使用 abstract 聲明,抽象方法必須被子類(lèi)實(shí)現(xiàn)(抽象方法必須使用 abstract 關(guān)鍵字聲明,且可以包含訪問(wèn)修飾符)
abstract class Person {
  public love: string;
  constructor(love: string) {
    this.love = love;
  }
  abstract sayLove(): string; // 必須在派生類(lèi)中實(shí)現(xiàn)
}
class Man extends Person{
  constructor(love: string){
    super(love)
  }
  sayLove() {
    return `my love is ${this.love}`;
  }
}
let me = new Man('TS');
console.log(me.sayLove()); // my love is TS

把類(lèi)當(dāng)做接口使用

類(lèi)定義會(huì)創(chuàng)建兩個(gè)東西:類(lèi)的實(shí)例類(lèi)型和一個(gè)構(gòu)造函數(shù),因?yàn)轭?lèi)可以創(chuàng)建出類(lèi)型,所以能夠在允許使用接口的地方使用類(lèi)。

class Person {
  name: string;
  age: number;
}
interface Man extends Person {
  love: string;
}
let me: Man = {
  name: 'funlee',
  age: 18,
  love: 'TS'
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容