TypeScript躬行記(3)——類


  類是對對象的抽象,描述了對象的特征和行為,而對象就是類的實例。ES6引入了類的概念(相關內容可參考ES類ES6類的繼承兩節),TypeScript在此基礎上,不僅根據ES7等規范完善了類的語法,還添加了許多其它語法。而在使用TypeScript的類時,不必關心兼容性問題,因為這些工作已由編譯器完成。

  下面是一個簡單的類,包含3個成員:帶private修飾符的name屬性、構造函數constructor()和getName()方法,最后一句使用new運算符創建了Person類的實例,並調用了一次它的構造函數。

class Person {
  private name: string;
  constructor(name: string) {
    this.name = name;
  }
  getName() {
    return this.name;
  }
}
let worker = new Person("strick");

  編譯后的代碼如下所示,通過傳統的構造函數和基於原型的繼承來模擬一個類。

var Person = /** @class */ (function() {
  function Person(name) {
    this.name = name;
  }
  Person.prototype.getName = function() {
    return this.name;
  };
  return Person;
})();
var worker = new Person("strick");

一、屬性

  在ES6中,實例屬性(即自有屬性)得作為this對象的屬性存在,並且一般都會在構造函數中執行初始化,而TypeScript允許在類中直接定義實例屬性,如下所示。

class Person {
  constructor(name: string) {
    this.name = name;
  }
}
//TypeScript中的實例屬性
class Person {
  name: string;
}

  不僅如此,TypeScript還提供了存在於類本身上的靜態屬性,即不需要實例化就能調用的屬性。在下面的示例中,為age屬性添加了static關鍵字,使其成為靜態屬性,通過類的名稱就能直接調用它。

class Person {
  static age: number;
}
Person.age = 28;

二、修飾符

  修飾符是用於限定成員或類型的一種符號,TypeScript包含三個訪問修飾符:public、private和protected,以及一個成員修飾符:readonly。

1)public

  在TypeScript中,成員默認都是public的,即在派生類(也叫子類)或類的外部都能被訪問。在下面的示例中,Person類中的name屬性是公共的,Programmer類繼承了Person類。注意,當派生類包含一個構造函數時,必須調用super()方法,執行基類(即父類)的構造函數,並且該方法得在訪問this對象之前調用。

class Person {
  public name: string;
  constructor(name: string) {
    this.name = name;
  }
}
class Programmer extends Person {
  constructor(name: string) {
    super(name);
  }
}

  在初始化Person類或Programmer類之后,就能通過創建的實例來訪問name屬性,如下所示。

let person = new Person("strick");
person.name;            //"strick"
let programmer = new Programmer("freedom");
programmer.name;        //"freedom"

2)private

  當成員被修飾為private時,只能在類的內部訪問它,例如在基類Person中聲明一個私有的age屬性,在類的實例或派生類的實例中訪問age屬性都會在編譯階段報錯,如下所示。

class Person {
  private age: number;
}
person.age;            //錯誤
programmer.age;        //錯誤

  當構造函數被修飾為private時(如下所示),包含它的類既不能實例化,也不能被繼承。

class Person {
  private constructor(name: string) {
    this.name = name;
  }
}

3)protected

  此修飾符與private的行為類似,只是有一點不同,即在派生類中還是可以訪問它的,例如在基類Person中聲明一個受保護的school屬性,在派生類中就能訪問到它,如下所示(省略了基類的構造函數)。

class Person {
  protected school: string;
}
class Programmer extends Person {
  constructor(name: string) {
    super(name);
    this.school = "university";
  }
}

  當構造函數被修飾為protected時(如下所示),包含它的類不能實例化,但可以被繼承。

class Person {
  protected constructor(name: string) {
    this.name = name;
  }
}

4)readonly

  當成員被修飾為readonly時,它就變成只讀的,只能在聲明時或構造函數里初始化,其它地方對它的修改都是禁止的,如下所示。

class Person {
  readonly gender: string = "";        //正確
  constructor() {
    this.gender = "";                //正確
  }
}
let person = new Person();
person.gender = "";                 //錯誤

  當readonly與其它修飾符一起使用時,需跟在它們后面,如下所示。

class Person {
  protected readonly gender: string;
}

三、參數屬性

  參數屬性可以便捷的在構造函數中聲明並初始化一個類的屬性,此類參數會與三個訪問修飾符或readonly組合使用,如下所示。

class Person {
  constructor(public name: string) { }
}

  構造函數中的name是一個參數屬性,相當於在Person類中聲明一個name屬性,並在構造函數中為其初始化,如下所示。

class Person {
  public name: string;
  constructor(name: string) {
    this.name = name;
  }
}

四、抽象類

  抽象類是供其它派生類繼承的基類,它與接口一樣,不能被實例化,但可以包含成員的實現細節。在聲明一個類時,如果包含abstract關鍵字,那么這就是一個抽象類,如下所示,當對其進行實例化時,會在編譯時報錯。

abstract class Person { }
let person = new Person();        //錯誤

  在抽象類中,會聲明一個或多個帶abstract類修飾符的抽象方法,它們只有名稱,不包含實現細節,可與訪問修飾符組合使用,如下所示。

abstract class Person {
  protected abstract work(): void
}

  派生類中必須實現繼承的抽象方法(如下所示),否則會在編譯階段報錯。

class Programmer extends Person {
  public work(): void {
    console.log("code");
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM