1. 继承

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); }      // super
    move(distanceInMeters = 5) {
        console.log("Slithering...");
        super.move(distanceInMeters);
    }
}

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

如果子类包含了构造函数,那么它必须调用 super(), 它会执行基类的构造函数。并且在构造函数访问this属性之前,一定要调用 super();

2. 公共,私有与受保护的修饰符

在 typescript 里,成员都默认为 public

class Animal {
    public name: string;
    public constructor(theName: string) {
        this.name = theName;
    }
    public move(distabceInMeters: number) {
        ...
    }
}

private

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

new Animal('CAT').name;      // error, 不能再声明它的类之外访问

protected

protected 与 privated 类似,但是 protected 成员在子类中可以访问。

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}.`;
    }
}

let howard = new Employee("Howard", "Sales");
console.log(howard.getElevatorPitch());  // 成功,在子类中访问属性
console.log(howard.name); // 错误,不能在子类之外访问

3. 静态属性

class Grid {
    static origin = {
        x: 0,
        y: 0
    }
    calculate(point: { x: number, y: number } ) {
        let xDist = point.x - Grid.origin.x;      // 静态属性的使用,直接用类.属性名
    }
}

4. 抽象类

抽象类作为其它派生类的基类使用,不会直接被实例化。

使用 abstract 关键字定义抽象类和在抽象类内部定义抽象方法

abstract class Animal {
    abstract makeSound(): void;   // 抽象方法,必须在派生类中实现
    move(): void {

    }
}

5. 构造函数

在TypeScript中声明一个类的时候,实际上声明了很多东西,比如, 类的实例的类型

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
}

let greeter: Greeter;     // 表明 greeter 是 Greeter 类的实例的类型

除了类的实例的类型,我们可能还关注,类的类型

class Greeter {
    static standardGreeting = "Hello, there";
    greeting: string;
    greet() {
        if (this.greeting) {
            return "Hello, " + this.greeting;
        }
        else {
            return Greeter.standardGreeting;
        }
    }
}

let greeter1: Greeter;
greeter1 = new Greeter();
console.log(greeter1.greet());

// 得到 Gretter 的类的类型,这时候声明的变量,和 Gretter一样,可以被 new 
let greeterMaker: typeof Greeter = Greeter;
greeterMaker.standardGreeting = "Hey there!";

let greeter2: Greeter = new greeterMaker();
console.log(greeter2.greet());

即通过 typeof 操作符,可以得到类的类型。

5. 把类当接口使用

类定义会创建两个东西: 类的实例类型和一个构造函数,那么实例类型就可以当做接口去使用

class Point {
    x: number;
    y: number;
}

interface Point3d extends Point {  // 当做接口去继承
    z: number;
}

let point3d: Point3d = {x:1, y:2, z:3}

Last updated