面向對象編程,應該是目前使用最普遍的編程模式。 javascript
JavaScript是基於原型的語言,自從普遍使用以後,面向對象的改造一直沒停過,很多第三方庫都使用原型實現了JavaScript下面的類,如:MooTools,Backbone。再到ES6標準,直接原生支持了類定義,不過只能算語法糖級的支持。java
TypeScript對面向對象支持的更完全,很是接近Java、C#語言,支持接口、類、抽象、繼承、可見性等面向對象特性。編程
即同一類事物,咱們能夠把它抽象成一個描述,就是類。對外,咱們看到的就是這個類描述,它有什麼屬性,它能幹嗎,取決於它對外公開的屬性和方法。它的內部如何運做,咱們無需關注。 編程語言
好比咱們要用面嚮對象語言描述動物:動物有一個名字,動物能移動。它怎麼作到移動呢,外部是不用關心的。函數
若是抽象是基礎,那麼繼承就是面向對象的高峯。抽象給了編程語言描述世界的畫筆,那麼繼承就給了它色彩。 this
繼承類擁有父類公開的、保護的屬性和方法,同時還能夠添加本身的屬性和方法。code
通常分爲實現繼承、接口繼承。對象
再拿動物來講,鳥類是動物的一種,它不光繼承了動物的特性,它還有本身的專屬特性:它有翅膀,它能飛。繼承
多態簡單來講,就是同一個類的對象,表現出不一樣的特性,是繼承延伸出來的表現結果。接口
常見多態有覆蓋、重載兩類。
TypeScript中的類方法不支持真正意義上的重載,能夠經過增長可選參數來達到重載的目的。
具體的緣由,是由於重載在編譯以後,是以多個不一樣名的函數存在的,調用哪一個也是編譯的時候肯定的。而TypeScript須要支持JavaScript來調用它,JavaScript不知道編譯以後的函數名。
後面會拿一篇文章來分析。
仍是拿動物爲例,繼承並覆蓋move方法以後,鳥類實現了飛、魚類實現了遊。
// 知識點:抽象類 abstract class Animal { // 知識點:私有成員 private _name: string; // 知識點:存取器 get name(): string { return this._name; } constructor(name: string) { this._name = name; } // 知識點:抽象方法 abstract move(distance: number): void; }
// 知識點:實現抽象類的子類 class Bird extends Animal { // 知識點:只讀成員 // 知識點:靜態成員 static readonly classification = 'bird'; // 知識點:super() constructor(name: string) { super(name); } // 知識點:抽象方法實現 move(distance: number): void { console.log(`moved ${distance}.`) } } const enum MoveMode { WALK, FLY } // 知識點:子類 class Owl extends Bird { private _mode: MoveMode; get mode(): MoveMode { console.log('read move mode.'); return this._mode; } set mode(mode: MoveMode) { console.log('changed move mode.'); this._mode = mode; } // 知識點:super() constructor(name: string) { super(name); this._mode = MoveMode.FLY; } // 知識點:方法覆蓋 move(distance: number): void { switch (this._mode) { case MoveMode.FLY: console.log(`fly ${distance}.`); break; case MoveMode.WALK: console.log(`walked ${distance}.`); break; default:; } } }
從上述示例中,整理出如下知識點,請結合示例回顧,增強一下理解。
抽象類不能實例化,抽象方法不能實現,須要在子類中實現。
繼承了父類的類,是相對的。
類成員可見性
靜態成員屬於類
只讀,即初始化後不可修改,只能在聲明和構造函數裏初始化。
能夠像成員同樣來訪問,通常用來作一些處理,好比校驗,格式化等。
覆蓋父類方法,實現本身的特性。