[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);
    }
}
class Horse extends Animal {
    constructor(name: string) { super(name); }
    move(distanceInMeters = 45) {
        console.log("Galloping...");
        super.move(distanceInMeters);
    }
}
let sam = new Snake("Sammy the Python");
let tom: Animal = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);

【注】:子类的构造方法中,必须首先调用super(),这是强制执行的规则。

二、public、private、protected

1.public 公有

TypeScript中,成员默认为public

2.private 私有

当成员被标记成 private时,它就不能在声明它的类的外部访问,但是如果它被继承,子类里面还是有这个成员的,只是不能访问。

class Animal {
    private name: string;
    constructor(theName: string) { this.name = theName; }
}
new Animal("Cat").name; // 错误: 'name' 是私有的.

3.protected 保护

protected修饰符与 private修饰符的行为很相似,但有一点不同, protected成员在派生类中仍然可以访问。

【注】:构造函数也可以被标记成 protected。 这意味着这个类不能在包含它的类外被实例化,但是能被继承。

三、reanonly和参数属性

1.readonly

可以使用 readonly关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化

class Octopus {
    readonly name: string;
    readonly numberOfLegs: number = 8;
    constructor (theName: string) {
        this.name = theName;
    }
}
let dad = new Octopus("Man with the 8 strong legs");
dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.

2.参数属性

参数属性通过给构造函数参数前面添加一个访问限定符来声明。 就是说在构造函数里面直接定义成员变量

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

四、存取器

存取器用来控制对对象成员的访问,即必须符合一定的规则才能进行访问(get)或者修改(set)。

存取器对于对象内部来说类似于一个方法,对于对象外部则类似于一个成员变量。

一般把成员声明为私有,使用get 和 set 来控制在一定条件下的存取。

let 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 {
            console.log("Error: Unauthorized update of employee!");
        }
    }
}

let employee = new Employee();
employee.fullName = "Bob Smith"; // 对外则相当于一个成员变量,并且只有满足条件才能修改
if (employee.fullName) {
    alert(employee.fullName);
}

【注】:只带有 get不带有 set的存取器自动被推断为 readonly

五、静态属性

静态属性用static修饰,属于类而不是类的实例,访问时使用 类名.属性 

六、抽象类

抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。

abstract class Department {
    constructor(public name: string) {
    }
    printName(): void {
        console.log('Department name: ' + this.name);
    }
    abstract printMeeting(): void; // 必须在派生类中实现
}

class AccountingDepartment extends Department {
    constructor() {
        super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()
    }
    printMeeting(): void {
        console.log('The Accounting Department meets each Monday at 10am.');
    }
    generateReports(): void {
        console.log('Generating accounting reports...');
    }
}

let department: Department; // 允许创建一个对抽象类型的引用
department = new Department(); // 错误: 不能创建一个抽象类的实例
department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
department.printName();
department.printMeeting();
department.generateReports(); // 错误: 方法在声明的抽象类中不存在

七、高级技巧

1.类的实例类型

let greeter: Greeter;
greeter = new Greeter("world");

这里,我们写了 let greeter: Greeter,意思是 Greeter类的实例的类型是 Greeter

 

posted @ 2018-12-14 11:01  麦田里的小王子  阅读(188)  评论(0编辑  收藏  举报