理解 TypeScript 類

對象的設計圖:類

在ES5中,只有對象的概念,對象是經過構造函數建立出來的,構造函數自己也是對象。因此說JavaScript是一種基於對象的語言。程序員

ES6以後,有了class,也就是咱們的類,雖然class實質上是 JavaScript 現有的基於原型的繼承的語法糖。但咱們一樣能夠借鑑C#語言的面向對象的思想去理解它。讓咱們夠使用==基於類的面向對象的方式==。編程

類就是對象的設計圖紙,上面記錄着一個事物應該有哪些字段,哪些方法,但類不是個對象,只是對象的定義。經過new 一個類,咱們才能獲得一個對象,這個對象有類上描述的全部成員。bash

這就是基於類的面向對象的方式。程序員畫好了許許多多的設計圖(類)。而後new 它們,造成了一個一個的對象,對象之間彼此關聯,協做。咱們的程序就這樣運行了。函數

因此咱們有了類的概念,通曉類與對象的關係後,這會影響咱們的編程思惟方式,須要什麼東西,先定義個類,在new出個對象,讓其工做。咱們的對象更加具象了,它有類給予它的定義。學習

認識類

下面咱們就來認識TypeScript中的類ui

定義類

class Person { 
}
複製代碼

類中的成員

類內的成員有:字段、存取器、構造函數、方法。this

字段

class Person { 
    age: number; // 這就是一個字段
}
複製代碼

類中的變量成員。能夠被實例化的對象設置和讀取。也能夠被類內其餘成員設置和讀取。spa

存取器

class Person {
    private _age: number;

    get age(): number {
        return this._age;
    }

    set age(newName: number) {
        if(newName > 150){
            this._age = 150;
        }
        this._age = newAge;
    }
}
複製代碼

這裏的get/set方法,就是_age變量的存取器。首先咱們爲_age變量添加一個private修飾符。表示它是個私有變量,禁止外部對它的訪問。設計

const person = new Person();
person._age // 這句會報錯,TS不容許咱們讀取私有變量。
複製代碼

要想使用_age,須要利用存取器:code

const person = new Person();
person.age = 15; // 使用set age方法
const age = pereson.age; // 使用get age方法
複製代碼

使用存取器的好處是對變量的訪問和設置,有了控制。原則上類內部的變量,外部是不能訪問的,這就是封裝性。要想訪問,只能經過存取器方法。

構造函數

class Person {
    private _age: number;
    
    constructor(age: number) {
        this._age = age;
    }
}
複製代碼

constructor就是類的構造器,他的使用以下:

const person = new Person(15);
複製代碼

構造器就是咱們在new一個類的時候,調用的方法。

方法

JavaScript中,都叫函數,可是有了類以後,類中的函數成員,就叫方法。

class Person {
    eat() { 
        ....
    }
    drink() {
        
    }
}
複製代碼

這裏的eat和drink,就是Person類的方法。

this關鍵字

和原生js中捉摸不定的this不一樣,類中的this,很是好理解,它表示當前類的實例。

類的繼承

繼承,本質上講是一種代碼重用機制。 類的繼承是指一個類繼承另外一個類,那麼這個類的實例上,也會有被繼承類的屬性和方法。

class Animal {
    move(distanceInMeters: number = 0) {
        console.log(`Animal moved ${distanceInMeters}m.`);
    }
}

class Dog extends Animal {
    bark() {
        console.log('Woof! Woof!');
    }
}

const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();
複製代碼

extends關鍵字就是指Dog類繼承自Animal類。 Animal叫作父類。Dog叫作子類。

說到類的繼承,一樣帶來了一些問題,須要咱們瞭解一下。

  1. 父類中有的方法,子類也有,會怎麼樣?
  2. 子類想使用父類的構造函數,怎麼辦?

重寫

class Animal {
    move(distanceInMeters: number = 0) {
        console.log(`Animal moved ${distanceInMeters}m.`);
    }
}

class Dog extends Animal {
    move(distanceInMeters: number = 0) {
        console.log(`Dog moved ${distanceInMeters}m.`);
    }
    bark() {
        console.log('Woof! Woof!');
    }
}

const dog: Animal = new Dog();
dog.move(10); // Dog moved 10
複製代碼

Dog類對Animal的move類進行了重寫,調用Dog實例的move方法時,會調用Dog類重寫的move方法。

super關鍵字

class Animal {
    name: string;
    constructor(theName: string) { this.name = theName; }
}

class Dog extends Animal {
    constructor(name: string) { super(name); }
}
複製代碼

若是子類想使用父類中構造函數的邏輯,在子類的構造函數中,super()就是指父類構造函數。

訪問修飾符

TypeScript還爲咱們提供了類成員的訪問修飾符。public,private,protected。表明了成員的三個不一樣的訪問級別。

  1. public:默認的訪問級別,不寫默認就是public。
  2. private: 只能被類內部訪問,不能被類外部訪問。
  3. protected: 只能被類內部,繼承的類內部訪問,不能被外部訪問。

使用方式:

class Person {
    private name: string;
    protected age: string;
    public height: string;
}

const john = new Person("John");
john.name; // 報錯
jonh.age; // 報錯
jonh.height; // 正確

複製代碼

上面看到private和protected在類的外部,都不能夠訪問,public的能夠。那麼private和protected有什麼區別呢?

class Employee extends Person {
    getInfo() {
        this.name; // 報錯
        this.age; // 正確
    }
}
複製代碼

區別就在於在繼承類中,protected的成員,仍然能夠被訪問到,可是private的不行。

只讀屬性

可使用readonly關鍵字將屬性設置成功只讀,至關於類字段的const。

class Person {
  readonly name: string = 'john'; // 我只讀
  constructor(theName: string) {
    this.name = theName; // 能夠
  }

  setName() {
    this.name = 'lili'; // 報錯
  }
}
複製代碼

只能在初始化和構造函數中賦值,其餘地方不容許賦值。

靜態屬性

類中的成員還能夠用static關鍵字來修飾,那麼它就成了全部實例共有的成員。

class Person {
  static globalPeopleCount: number = '7000000000';
}
const john = new Person();
john.globalPeopleCount += 1;

const lili = new Person();
lili.globalPeopleCount // 7000000001

複製代碼

抽象類

抽象類是一種不能被實例化的類,它的目的就是用來繼承的,抽象類裏面能夠有抽象的成員,就是本身不實現,等着子類去實現。

抽象類和抽象成員,都是用abstract修飾:

abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log('roaming the earch...');
    }
}
複製代碼

抽象類中仍是能夠有具體實現的,這樣子類若是不實現,能夠繼承抽象類中的實現。

結束語

學習TS中的類,理解基於類的面向對象思惟,能夠幫助咱們更好的應用面向對象思惟,去解決項目的問題。

相關文章
相關標籤/搜索