Typescript 類

ECMAScript 往事

在 ES6 以前是沒有這個概念的,都是經過構造函數來實現同等效果的,繼承的實現經過原型鏈。javascript

Typescript 除了實現 ES6 類 class 的功能外還有其餘特性。一塊兒看看。java

概念串講掃盲

  • 類(class),定義事物的抽象特性(屬性和方法);
  • 抽象類(Abstract class),可讓其餘類繼承的基類(不容許實例化),抽象方法必須在子類中實現;
  • 接口(interface):不一樣類公有屬性或方法,可抽象成一個接口,接口能夠被類實現(implements)。類的繼承只能是一個,但能夠被實現屢次;
  • 存取器(setter and getter):屬性的賦值與讀取;
  • 修飾符(modifiers):是一些關鍵字,限定成員或類型的性質(public、protect、private),Typescript 支持;
  • 對象(object),類的實例,經過 new 生成實現;
  • 面向對象(OOP)特性:封裝、繼承和多態;
  • 封裝(encapsulation):將對數據屬性的處理細節隱藏起來,對外只暴露接口。外部調用不須要知道細節,就能訪問該對象,這也保證了外部沒法改變內部數據屬性;
  • 繼承(inheritance):子類繼承父類,子類擁有父類全部特性,還能夠有本身具體的特性;
  • 多態(polymorphism):由繼承產生不一樣的類,對同一方法有不一樣的響應;

ES6 類的使用

ES6 咱們都很熟悉。使用 new 生成實例,會自動調用構造函數,而構造函數用 constructor 定義。git

實例、構造函數、屬性和方法

// es6.js
class Animal {
    constructor(name) {
        this.name = name;
    }
    showName() {
        return `我是${this.name}`
    }
}

let animal = new Animal('動物');
console.log(animal.showName()); // 我是動物
複製代碼

繼承與多態

派生類使用 extends 實現繼承,用 super 來執行基類的構造函數。es6

  • 基類即超類或父類;
  • 派生類即子類;
// es6.js
class Cat extends Animal {
    // constructor 沒有本身的屬性,可不寫
    constructor(name) {
        super(name);
    }

    showName() {
        return `我是一隻${this.name}`
    }
}

let cat = new Cat('貓');
console.log(cat.showName()); // 我是一隻貓
複製代碼

存取器

// es62.js
class Animal {
    constructor(name) {
        this.name = name;
    }
    get newName() {
        return `獲取: ${this.name}`;
    }
    set newName(value) {
        this.name = `新的${value}`
    }
}

let animal = new Animal('動物');
animal.newName = '大動物';
console.log(animal.newName);
複製代碼

靜態方法

就是使用 static 定義方法,僅供本身使用,因此無需實例化,實例不能調用。github

// es63.js
class Animal {
    static isAnimal(animal) {
        return animal instanceof Animal;
    }
}

let animal = new Animal('動物');
console.log(Animal.isAnimal(animal)); // true
console.log(animal.isAnimal(animal)); // TypeError: animal.isAnimal is not a function
複製代碼

ES7 類的用法

實例屬性

ES6 中實例屬性都是在構造函數 construction 中定義,在 ES7 中直接在類裏面寫就能夠了。typescript

// es64.js
class Animal {
    name = '動物';

    constructor() {
        // ...
    }
}

let animal = new Animal();
console.log(animal.name); // 動物
複製代碼

靜態屬性

既然實例屬性能夠直接在類中直接定義,那靜態屬性也能夠這樣markdown

// es65.js
class Animal {
    static name = '動物';

    constructor() {
        // ...
    }
}

let animal = new Animal();
console.log(Animal.name); // 動物
console.log(animal.name); // undefined
複製代碼

Typescript 類的用法

新增了顯眼並不新鮮的修飾符 publicprivateprotectedreadonly函數

  • public 所修飾的屬性和方法是公共的,任意使用;
  • private 所修飾的屬性和方法是私有的,僅供類自身使用;
  • protected 所修飾的屬性和方法是受保護的,僅供類自身和子類使用;
  • readonly 所修飾的屬性是隻讀的,必須在聲明時或構造函數裏被初始化;
// class.ts
class Star {
    public name: string = 'pr';
    protected age: number = 18;
    private weight: number = 90;
    readonly gender: string = '女';

    public constructor(name: string, age: number, weight: number, gender: string) {
        this.name = name;
        this.age = age;
        this.weight = weight;
        this.gender = gender;
    }
}

class ChinaStar extends Star {
    constructor(name: string, age: number, weight: number, gender: string) {
        super(name, age, weight, gender);
    }

    showName(){
        return `我是${this.name}`
    }

    showAge(){
        return `我實際年齡${this.age}`
    }

    showWeight(){
        return `個人體重${this.weight}`
    }

    showGender(){
        return `個人性別${this.gender}`
    }
}

let pr = new ChinaStar('pr', 30, 120, '男');
pr.name = '江湖再見';
pr.age = 18;
pr.weight = 100;
pr.gender = '女';

console.log(pr.name);
console.log(pr.age);
console.log(pr.weight);
console.log(pr.gender);

console.log(pr.showName());
console.log(pr.showAge());
console.log(pr.showWeight());
console.log(pr.showGender());

// 0.0.9/class.ts:29:28 - error TS2341: Property 'weight' is private and only accessible within class 'Star'.
    // 29 return `個人體重${this.weight}`

// 0.0.9/class.ts:39:4 - error TS2445: Property 'age' is protected and only accessible within class 'Star' and its subclasses.
    // 39 pr.age = 18;
      
// 0.0.9/class.ts:40:4 - error TS2341: Property 'weight' is private and only accessible within class 'Star'.
    // 40 pr.weight = 100;
      
// 0.0.9/class.ts:41:4 - error TS2540: Cannot assign to 'gender' because it is a read-only property.
    // 41 pr.gender = '女';
      
// 0.0.9/class.ts:44:16 - error TS2445: Property 'age' is protected and only accessible within class 'Star' and its subclasses.
    // 44 console.log(pr.age);
       
// 0.0.9/class.ts:45:16 - error TS2341: Property 'weight' is private and only accessible within class 'Star'.
    // 45 console.log(pr.weight);
複製代碼

從例子中可看到oop

  • 只有屬性 name 能在實例中使用;
  • 只有屬性 nameage 能在子類中使用;
  • 沒法分配給「gender」,由於它是隻讀屬性;

注: 基類的構造函數使用 this 的屬性以前必須調用 super(),這是 Typescript 的一項要求。post

抽象類

不被實例化,只給基類使用。可用關鍵字 Abstract 定義抽象類和其內部定義的抽象方法。不一樣於接口,抽象類能夠包含成員的實現細節。

// abstract.ts
abstract class Animal2 {
    abstract say(): void;
    move(): void{
        console.log('移動');
    }
}
複製代碼

抽象類中的抽象方法不含具體實現(這點和接口很類似,都定義了方法簽名不含方法體),但必須在派生類中實現。

// abstract2.ts
// 抽象類
abstract class AbstractPerson {
    constructor(public name: string, public age: number, public weight: number) { }

    showName(): string {
        return `個人名字是${this.name}`;
    }

    abstract showAge(): void;
}

// 基類
class Person extends AbstractPerson {
    constructor(name: string, age: number, weight: number) {
        super(name, age, weight);
    }
    showAge(): void {
        console.log(`個人年齡${this.age}`)
    }
    showWeight(): void {
        console.log(`個人體重${this.weight}`)
    }
}


let person1: AbstractPerson;
let person2: AbstractPerson;

person1 = new AbstractPerson('pr', 30, 110);
person2 = new Person('pr', 30, 110);

console.log(person2.showName());
person2.showAge();
person2.showWeight();


// 0.0.9/abstract2.ts:29:11 - error TS2511: Cannot create an instance of an abstract class.
    // 29 person1 = new AbstractPerson('pr', 30, 110);
       
// 0.0.9/abstract2.ts:34:9 - error TS2339: Property 'showWeight' does not exist on type 'AbstractPerson'.
    // 34 person2.showWeight();
複製代碼
  • 不能給抽象類生成實例;
  • 方法 showWeight 在抽象類 AbstractPerson 中上不存在;

本次代碼 Github

你能夠...

上一篇:Typescript 枚舉

下一篇:Typescript 類與接口

目錄:Typescript 小書之入門篇

相關文章
相關標籤/搜索