TypeScript中的面向對象編程

面向對象也便是OOP(Object Oriented Programming),是計算機的一種編程架構,OOP的基本原則是計算機是由子程序做用的單個或者多個對象組合而成,包含屬性和方法的對象是類的實例,面向對象的基本特性是:封裝、繼承、多態、抽象。程序員

一直到今天對於JavaScript是不是面向對象的語言定論仍然沒有一致的結果,由於JavaScript(ES5)中沒有類的概念,而是直接使用對象來實現編程,使用原型來實現繼承,一種基於對象和事件驅動的弱類型動態語言。因爲這些不一而足的缺點,微軟推出了JavaScript的超集語言--TypeScriptTypeScript就是一個基於類的面向對象編程語言編程

1. SOLID原則

在早期的軟件開發中,開發者一般使用過程式的程序語言編寫代碼。在過程式的語言中,程序遵循自頂向下的原則開發,而且邏輯都包裹在函數中。當程序員意識到過程式的語言沒法提供他們須要的抽象層次、可維護性和複用性時,出現了OOP,並總結了5個OOP開發者須要遵照的原則,以便更容易地建立出可維護和可拓展的系統。bash

  • 單一職責原則(SRP):代表軟件組件(函數、類、模塊)必須專一與單一的任務(只有單一的職責);
  • 開/閉原則(OCP):代表軟件設計時必須考慮到代碼的擴展性,程序的發展必須最少地修改已有的代碼(對已有的修改封閉);
  • 里氏替換原則(LSP):代表只要繼承的是同一個接口,程序裏任意一個類均可以被其餘對象(應該能夠是在不改變程序正確性的前提下被它的子類)所替換;
  • 接口隔離原則(ISP):代表應該將很是大的接口拆分紅一些小的更具體的接口,多個特定客戶端接口要好於一個寬泛用途的接口;
  • 依賴反轉原則(DIP):代表一個方法應該聽從依賴於抽象藉口而不是一個實例(類的概念);

2. 類

咱們用類去描述一個對象或者實例,一個類由名字、屬性、方法組成。架構

class Person {
  public name: string;
  public surname: string;
  public email: Email;
  constructor(name: string, surname: string, email: Email) {
    this.name = name;
    this.surname = surname;
    this.email = email;
  }
  greet() {
    console.log(`Hi, ${this.name}`);
  }
}

var me : Person = new Person('lewis', 'lewislv', 'lewis@163.com');
複製代碼

一個類要遵循單一職責原則(SRP),可讓咱們更容易的看出它的做用,進而去擴展它,這樣就用到類的封裝和抽象的概念;app

3. 接口

在傳統的面向對象的編程中,一個類能夠擴展另外一個類,也能夠實現一個或多個接口;實現一個接口能夠被看做是簽署了一份協議,必須遵照它的規則。接口的規則是屬性和方法的簽名,咱們必須實現它們;框架

在TypeScript中接口有兩點不一樣:編程語言

  • 接口能夠擴展其餘接口或者類;
  • 接口能夠定義數據和行爲而不僅是行爲;
interface UserInterface {
    name: string;
    password: string;
}

var user: UserInterface = {
    name: '',
    password: ''  // 容易遺漏錯誤性
}
複製代碼

4. 繼承

面向對象編程最重要的特性之一就是能夠擴展已有的類,它容許咱們建立一個類(子類),從已有的類(父類)上繼承全部的屬性和方法,子類能夠包含父類中沒有的屬性和方法;函數

class Teacher extends Person {
    teach() {
        console.log('Welcome to class!');
    }
}

var teacher = new Teacher('lewis', 'lewislv', 'lewis@163.com');
teacher.teach();
teacher.greet();
複製代碼

有時咱們但願子類能提供父類中同名方法的特殊實現,能夠用保留字super達到這個目的。ui

class Teacher extends Person {
    public subjects: string [];
    constructor(name: string, surname: string, email: Email) {
        super(name, surname, email);
        this.subjects = subjects;
    }
    greet() {
        super.greet();
        console.log(`I teach ${this.subjects!}`);
    }
}

var teacher = new Teacher('lewis', 'lewislv', 'lewis@163.com');
teacher.teach();
teacher.greet();
複製代碼

5. 範型類和範型約束

如同範型函數同樣,範型類可以幫助咱們避免重複代碼,有時候咱們可能會須要約束範型類,一個可行的解決方案是在範型類或函數內使用typeof操做符來驗證參數範型的類型;this

interface MyInterface {
    doSomething();
}
interface MySecondInterface {
    doSomethingElse();
}

class Example<T extends MyInterface, MySecondInterface> {
    private genericProperty: T;
    useT() {
        this.genericProperty.doSomething();
        this.genericProperty.doSomethingElse(); // 編譯錯誤
    }
}
複製代碼

6. 命名空間

TypeScript提供了命名空間特性,主要用於組織代碼,若是在寫一個大型應用,這時能夠用命名空間包裹那些有聯繫的接口、類和對象,並使代碼更加容易跟蹤和理解。

namespace app {
    export class UserModel {
        // ...
    }
}
複製代碼

當聲明一個命名空間時,全部實體部分默認都是私有的,可使用export關鍵字導出公共部分,也能夠在命名空間內聲明另外一個命名空間;

namespace app {
    export namescpace models {
        export class UserModel {
            // ...
        }
    }
}
複製代碼

總結

以上就是TypeScript的一些面向對象編程的概念,TypeScript的好處很明顯,在編譯時就能檢查出不少語法問題而不是在運行時。目前國內使用Typescript的團隊並很少,我以爲寫出的代碼是否易於維護、優雅,不在於用了什麼框架、語言,而在於開發者自己,可是不能保證每一個人都不犯錯,誠然好的框架和語言能間接幫助開發者寫出規範的代碼,因此若是有必定技術沉澱的團隊仍是建議早點使用TypeScript

更多精彩內容歡迎關注個人我的公衆號【天道酬勤Lewis】

相關文章
相關標籤/搜索