avatar
童琦杰
Feb 28, 2017Technology

Typescript - 类

类定义

跟绝大数面对对象语言一样,TypeScript中的类也支持定义构造方法、实例属性、实例方法。

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

let greeter = new Greeter("world");

使用关键字new创建一个实例。

继承

TypeScript支持Class继承,使用关键字extends

typescript
class Animal {
    name: string;
    constructor(theName: string) { this.name = theName; }
    move(distanceInMeters: number = 0) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

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

子类若包含构造函数,则必须调用super()来执行基类的构造函数。

public、private、protected访问修饰符

TypeScript中类成员访问修饰符默认是public,即类外部可以自由地访问类中成员。

typescript
class Animal {
    public name: string;
    public constructor(theName: string) { this.name = theName; }
    public move(distanceInMeters: number) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

使用private修饰的类成员不能被类外部代码访问。

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

使用protected修饰的类成员能被子类中的代码访问。

typescript
class Person {
    protected name: string;
    constructor(name: string) { this.name = name; }
}

class Employee extends Person {
    private department: string;

    constructor(name: string, department: string) {
        super(name);
        this.department = department;
    }

    public getElevatorPitch() {
        return `Hello, my name is ${this.name} and I work in ${this.department}.`;
    }
}

若使用protected修饰构造函数,则该类不允许在类外部实例化,但是可以被继承。

readonly修饰符

使用关键字readonly修饰的属性只能在属性声明时或构造函数中对它赋值。

typescript
class Octopus {
    readonly name: string;
    readonly numberOfLegs: number = 8;
    constructor (theName: string) {
        this.name = theName;
    }
}

参数属性

当构造函数的参数使用访问修饰符或readonly修饰符修饰时,编译器自动定义一个相同名称的属性并给它赋值。

typescript
class Octopus {
    readonly numberOfLegs: number = 8;
    constructor(readonly name: string) {
    }
}

属性访问器

使用关键字getset定义属性访问器。

typescript
class Employee {
    private _fullName: string;

    get fullName(): string {
        return this._fullName;
    }

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

let employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
    console.log(employee.fullName);
}

静态属性

使用关键字static声明静态属性。

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

抽象类

使用关键字abstract定义抽象类,抽象类不能被实例化。在抽象类中,可以使用abstract定义抽象方法。

typescript
abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log("roaming the earth...");
    }
}

抽象方法必须在子类中实现。

实现接口

使用关键字implements约束类必须实现指定的接口。

typescript
interface ClockInterface {
    currentTime: Date;
}

class Clock implements ClockInterface {
    currentTime: Date;
    constructor(h: number, m: number) { }
}
© 2015-2022 tongqijie.com 版权所有沪ICP备17000682号