【TypeScript】TypeScript 學習 3——類


在 EcmaScript 6 中,我們將會擁有原生的類,而不是像現在通過原型鏈來實現。使用 TypeScript 我們能提前體驗這一特性。

首先來看看一個簡單的例子:

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

var greeter = new Greeter("world");

我們使用 class 關鍵字來定義了,使用 constructor 來定義構造函數,使用 this 關鍵字來指代當前對象。

除了構造函數關鍵字外,語法跟 C# 和 java 是比較像的。

  • 繼承

作為面向對象三大基本特征之一,TypeScript 當然支持繼承。

class Animal {
    name:string;
    constructor(theName: string) { this.name = theName; }
    move(meters: number = 0) {
        alert(this.name + " moved " + meters + "m.");
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move(meters = 5) {
        alert("Slithering...");
        super.move(meters);
    }
}

class Horse extends Animal {
    constructor(name: string) { super(name); }
    move(meters = 45) {
        alert("Galloping...");
        super.move(meters);
    }
}

var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");

sam.move();
tom.move(34);

跟接口的繼承一樣,都是使用 extends 關鍵字來繼承。在子類中,我們使用 super 關鍵字來訪問父類。在上面代碼中我們看到方法的參數中有等於號,這表示方法參數的默認值。如果我們調用該方法時,不寫該參數或者傳入 undefined,那么這個參數就會被賦予默認值。

sam.move();
sam.move(undefined);

即上面這兩段代碼是等價的。

注意:TypeScript 跟 C# 和 java 一樣,是不支持多繼承的(雖然可以通過原型鏈實現)。

  • 訪問修飾符

在 TypeScript 中,現在僅有兩種訪問修飾符,分別是 public 和 private。

在之前的代碼中,我們都能夠正常訪問到類中定義的屬性。那么可見,類的屬性默認的訪問修飾符是 public 的。

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

class Rhino extends Animal {
    constructor() { super("Rhino"); }
}

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

var animal = new Animal("Goat");
var rhino = new Rhino();
var employee = new Employee("Bob");

animal = rhino;
animal = employee; //error: Animal and Employee are not compatible

我們將之前的代碼中的屬性的訪問修飾符修改為 private 之后,就會發現編譯無法通過了。

  • 參數屬性

訪問修飾符不僅僅可以作用於屬性,還能作用於構造函數參數。這個是 TypeScript 中的一個語法糖。

class Animal {
    constructor(private name: string) { }
    move(meters: number) {
        alert(this.name + " moved " + meters + "m.");
    }
}

那么構造函數中的 name 參數將會生成一個 private 的屬性。

訪問器

有時候我們在設置屬性的時候,希望對輸入進行檢查,這時候就需要用到訪問器了。

var passcode = "secret passcode";

class Employee {
    private _fullName: string;

    get fullName(): string {
        return this._fullName;
    }
    
    set fullName(newName: string) {
        if (passcode && passcode == "secret passcode") {
            this._fullName = newName;
        }
        else {
            alert("Error: Unauthorized update of employee!");
        }
    }
}

var employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
    alert(employee.fullName);
}

上面我們就為 fullName 屬性定義了 get 和 set 訪問器了。

  • 靜態屬性

在前面,我們定義的都是實例屬性。那么如何定義靜態屬性呢?使用 static 關鍵字就可以了。

class Grid {
    static origin = {x: 0, y: 0};
    calculateDistanceFromOrigin(point: {x: number; y: number;}) {
        var xDist = (point.x - Grid.origin.x);
        var yDist = (point.y - Grid.origin.y);
        return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
    }
    constructor (public scale: number) { }
}

var grid1 = new Grid(1.0);  // 1x scale
var grid2 = new Grid(5.0);  // 5x scale

alert(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
alert(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));

注意的是,要訪問靜態屬性,必須加上該靜態屬性所在的類作為前綴。

另外,靜態屬性也能配合訪問修飾符使用。

class Test {
    private static _age: number;
    static get age(): number {
        return Test._age;
    }
    static set age(value: number) {
        Test._age = value;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM