TypeScript系列(四)類的初體驗

類的介紹

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

類的成員修飾符

類的成員修飾符能夠有如下幾種,publicprivateprotected以及readonlyide

public
typescript中,成員默認都是public,也能夠明確的寫出來。咱們能夠自由的訪問程序裏定義爲的public成員,包括實例和子類。函數

private
private的成員不能在類的外部訪問。實例和子類中都不行。當在構造函數constructor上加上private修飾符的話,那麼這個類既不能被實例化,也不能被繼承。this

protected
和私有化成員相似,可是受保護的成員能夠在子類中訪問。當constructor被聲明爲protected的時候,這個類就不能被實例化,只能被繼承,至關於一個基類使用。spa

readonly
readonly關鍵字將屬性設置爲只讀的。 只讀屬性必須在聲明時或構造函數裏被初始化。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');
    }
}
相關文章
相關標籤/搜索