TypeScript入门-类

▓▓▓▓▓▓ 大致介绍

  在ECMASript6中引入了类这一概念,通过class声明一个类。对于学习过C和C++的人应该不会陌生

 

▓▓▓▓▓▓ 类

  看一个简单的类:

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

let greeter = new Greeter('world');

  在上面的例子中,利用class关键字声明了一个类Greeter,在类中,定义了一个属性,一个构造函数和一个方法

 

▓▓▓▓▓▓ 继承

  类通常都是用来继承的,但是Typescript中的继承和C中的继承还是有点差别的

  例如:

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);

  首先定义了一个类Animal,之后利用关键字extends定义了一个继承Animal的类Snake,可以发现在Snake的构造函数里使用了super()方法,这是因为包含constructor函数的派生类必须调用super(),它会执行基类的构造方法。

  在继承类中重写了构造函数,super.move()是继承父类的方法

 

 

▓▓▓▓▓▓ public、private和protected

  这三个概念对于学习过C的人应该很容易理解

  public:公开的,在类外也是可以访问的

  之前写的类中都是默认为public

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

 

  private:私有的,只有在该类中可以访问,在继承类中都不可访问

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

let animal = new Animal('cat');
animal.name;//error

 

  protected:保护的,是介于public和private之间的,和private的区别就是在继承类中时可以访问的

class Animal {
    private name: string;
    protected sex: string;
    public constructor(message: string){
        this.name = message;
    }
}

class Snake extends Animal {
    constructor(message){super(message)};
    get(){
        console.log(this.name); //error
        console.log(this.sex);
    }
}

  在上面的例子中,name是private,在继承类中是不可以访问的,而sex是可以被访问的,当然这两个属性在类外都不可以被访问

  注意:如果一个类的构造函数被声明为protected,这意味着这个类不能在包含它的类外被实例化,但是能被继承。

 

▓▓▓▓▓▓ 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"; // error! name is readonly.

 

▓▓▓▓▓▓ 参数属性

  利用参数属性可以简写很多代码

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

//利用参数属性
class Octopus {
    constructor(public name: string){}
}

  这两段代码的作用是一样的

 

▓▓▓▓▓▓ 存取器

  TypeScript支持getters/setters来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。

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);
}

 

▓▓▓▓▓▓ 抽象类

  抽象类是供其它类继承的基类。 他们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法。抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。

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'); // constructors in derived classes must call super()
    }

    printMeeting(): void {
        console.log('The Accounting Department meets each Monday at 10am.');
    }

    generateReports(): void {
        console.log('Generating accounting reports...');
    }
}

let department: Department; // ok to create a reference to an abstract type
department = new Department(); // error: cannot create an instance of an abstract class
department = new AccountingDepartment(); // ok to create and assign a non-abstract subclass
department.printName();
department.printMeeting();
department.generateReports(); // error: method doesn't exist on declared abstract type

 

参考资料:

   TypeScript Handbook(中文版)

 

posted @ 2017-04-06 23:20  老板丶鱼丸粗面  阅读(344)  评论(0编辑  收藏