ES6以前Javascript是使用函數和基於原型的繼承來實現類的概念。而在Typescript中則能夠和ES6及更新的版本中同樣使用class
關鍵字,面向對象的方式使用類。這篇文章,就讓咱們一塊兒好好了解一下類。javascript
類能夠有本身的構造函數,屬性,以及方法。使用new
構造一個對象的實例。這個過程當中會調用類的構造函數,建立一個新對象,並在執行完構造函數後返回這個新對象;java
class Animal { // 構造函數默認返回Animal對象 constructor (msg: string) { this.name = msg; } name: string; run() { console.log('run'); } } let animal = new Animal('test');
這裏值得一提的是,雖然咱們用的是class關鍵字來使用類,可是咱們仍是要明白,這只是高級語法糖而已,其實最終仍是基於原型的。類的成員屬性都是實例屬性,不是在原型上,類的成員方法都是在原型上。以上面的例子說明,name
屬性就存在與實例 animal
,而方法run
則是在原型Animal.prototype
上。typescript
類的成員修飾符能夠有如下幾種,public
, private
, protected
以及readonly
。ide
public
在typescript
中,成員默認都是public
,也能夠明確的寫出來。咱們能夠自由的訪問程序裏定義爲的public
成員,包括實例和子類。函數
privateprivate
的成員不能在類的外部訪問。實例和子類中都不行。當在構造函數constructor
上加上private
修飾符的話,那麼這個類既不能被實例化,也不能被繼承。this
protected
和私有化成員相似,可是受保護的成員能夠在子類中訪問。當constructor
被聲明爲protected
的時候,這個類就不能被實例化,只能被繼承,至關於一個基類使用。spa
readonlyreadonly
關鍵字將屬性設置爲只讀的。 只讀屬性必須在聲明時或構造函數裏被初始化。prototype
static
使用static
修飾符的成員爲靜態成員,只能經過類名來訪問,舉個例子:code
class People { constructor() { } static name = 'Kobe'; } let p = new People(); console.log(p.name) // 會報錯,不能經過實例訪問 console.log(People.name); // Kobe
參數屬性
在構造函數的參數前使用修飾符聲明,那麼參數屬性直接聲明一個屬性成員,舉個例子:對象
class Foo { constructor(public name: string){ } } let f = new Foo('Mike'); // 能夠直接訪問name屬性 console.log(f.name); // Mike
TypeScript
經過getters
/setters
來截取對對象成員的訪問。 能有效的控制對對象成員的訪問。只帶有get不帶有set存取器的屬性會被自動推斷爲readonly
。
class Student{ private _name: string; get name() { return this._name } set name(value) { this._name = value; console.log('setter: ' + value); } } let s = new Student(); s.name = 'Tom'; // setter: Tom console.log(a.name); // Tom
抽象類就是隻能被繼承,不能實例化的類。使用abstract
關鍵字來定義抽象類和抽象方法。用來抽離事物的共性,實現代碼複用和擴展。其中抽象類的方法能夠有具體實現,也能夠沒有,沒有的話就必須在子類中實現,比較靈活。而後就是在派生類的構造函數中必須調用 super()。看下面的例子:
abstract class People{ abstract task(): void; // 必須被實現 sayHi(): void { console.log('Hi'); } } class Student extends People { constructor() { super(); } task(): void { console.log('learing'); } }
接口之間能夠相互繼承,類之間也能夠相互繼承。類能夠實現接口,接口能夠繼承類。主要舉兩個例子說明一下。
接口繼承接口
interface People { name: string; } // 接口繼承單個接口 interface Boy extends People { classNumber: number; } // 接口繼承多個個接口, 以 , 分隔 interface Student extends People, Boy { } // 對象具備兩個`interface`的屬性 let stu: Student = { name: 'Mike', classNumber: 5 }
接口繼承類
這種用法不是不少,至關於接口把類的成員抽象出來,只有成員結構,沒有具體實現。
class Component { name: string; dispaly(): void { console.log('displaying'); } } interface Widget extends Component { hide(): void; } // 類實現接口,必須實現兩個方法 class Button implements Widget { // name屬性也是必須的 name: string; dispaly(): void { console.log('displaying in Button'); } hide(): void { console.log('hiding'); } }