继承
使用继承来扩展现有的类。
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();
类从基类中继承了属性和方法。
如果基类、派生类中存在构造函数
//基类
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强制执行的一条重要规则。
输出结果:
Slithering...
Sammy the Python moved 5m.
Galloping...
Tommy the Palomino moved 34m.
公共,私有与受保护的修饰符
默认为 public: 默认为全部可见
理解 private:当成员被标记成 `private`时,它就不能在声明它的类的外部访问。
TypeScript使用的是结构性类型系统。 当我们比较两种不同的类型时,并不在乎它们从何处而来,如果所有成员的类型都是兼容的,我们就认为它们的类型是兼容的。
比较带有 `private`或 `protected`成员的类型的时候,情况就不同了。 如果其中一个类型里包含一个 `private`成员,那么只有当另外一个类型中也存在这样一个 `private`成员, 并且它们都是来自同一处声明时,我们才认为这两个类型是兼容的。 对于 `protected`成员也使用这个s规则。
就是说来自两个不同类的 `private`或 `protected`声明是完全不同的。
**理解 `protected`**:`protected`修饰符与 `private`修饰符的行为很相似,但有一点不同, `protected`成员在派生类中仍然可以访问。
构造函数也可以被标记成 `protected`。 这意味着这个类不能在包含它的类外被实例化,但是能被继承。
class Person {
protected name: string;
protected constructor(theName: string) { this.name = theName; }
}