typescript的高级特性(一)

1、类

先看一下例子:web

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

let greeter = new Greeter("world");

咱们看上面的例子中,咱们声明了一个Greeter类。这里面有3个成员:一个叫greeting的属性,一个构造函数和一个greet方法。
咱们在引用任何一个类成员的时候都用了this。它表示咱们访问的是类的成员。
咱们使用new构造了Greeter类实例,它会调用以前定义的构造函数,建立一个 Greeter类型的新对象,并执行构造函数初始化它。svg

2、继承

关键词:extends函数

class Animal {
    move(distanceInMeters: number = 0) {
        console.log(`Animal moved ${distanceInMeters}m.`);
    }
}

class Dog extends Animal {
    bark() {
        console.log('Woof! Woof!');
    }
}

const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();

类从基类中继承了属性和方法。 这里, Dog是一个 派生类,它派生自 Animal 基类,经过 extends关键字。 派生类一般被称做 子类,基类一般被称做 超类。this

由于 Dog继承了 Animal的功能,所以咱们能够建立一个 Dog的实例,它可以 bark()和 move()。
在上面的基础上,咱们能够作一个更复杂的例子:spa

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(),它会执行基类的构造函数。 并且,在构造函数里访问 this的属性以前,咱们 必定要调用 super()。 这个是TypeScript强制执行的一条重要规则。
在子类中,重写了从父类中继承的move方法,使得move方法根据不一样的类而具备不一样的功能。code

3、公共,私有与保护的修饰符

一、种类
成员的修饰符有三种:public(默认)privateprotectedxml

当成员被标记成private时,它就不能在声明它的类的外部访问对象

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

new Animal("Cat").name; // 错误: 'name' 是私有的.

二、
TypeScript使用的是结构性类型系统。 当咱们比较两种不一样的类型时,并不在意它们从何处而来,若是全部成员的类型都是兼容的,咱们就认为它们的类型是兼容的继承

然而,当咱们比较带有 private或 protected成员的类型的时候,状况就不一样了。 若是其中一个类型里包含一个 private成员,那么只有当另一个类型中也存在这样一个 private成员, 而且它们都是来自同一处声明时,咱们才认为这两个类型是兼容的。 对于 protected成员也使用这个规则。
下面咱们能够看一个例子:token

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

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

animal = rhino;//Animal和 Rhino共享了来自 Animal里的私有成员,因此是兼容的
animal = employee; // 错误: Animal 与 Employee 不兼容.

三、protected
protected与private很类似,可是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); // 错误

不能在 Person类外使用 name,可是咱们仍然能够经过 Employee类的实例方法访问,由于 Employee是由 Person派生而来的。