函数继承相对于 类 来说,缺点有两个:麻烦、在 ts 中缺少类型的检查。
继承
class Animal {
type = 'Animal';
say(name: string) {
console.log(`I'm ${name}!`);
}
}
class Dog extends Animal {
bark() {
console.log('Woof! Woof!');
}
}
const dog = new Dog();
dog.bark(); // => 'Woof! Woof!'
dog.say('Q'); // => I'm Q!
dog.type; // => Animal
公共、私有与受保护的修饰符
- public 修饰的是在任何地方可见、公有的属性或方法;
- private 修饰的是仅在同一类中可见、私有的属性或方法;
- protected 修饰的是仅在类自身及子类中可见、受保护的属性或方法。
1. private
TypeScript 中定义类的私有属性仅仅代表静态类型检测层面的私有。如果我们强制忽略 TypeScript 类型的检查错误,转译且运行 JavaScript 时依旧可以获取到 lastName 属性,这是因为 JavaScript 并不支持真正意义上的私有属性。
目前,JavaScript 类支持 private 修饰符的提案已经到 stage 3 了。相信在不久的将来,私有属性在类型检测和运行阶段都可以被限制为仅在类的内部可见。可以在proposal-private-methods中进行查看。
2. protected
虽然我们不能通过派生类的实例访问protected修饰的属性和方法,但是可以通过派生类的实例方法进行访问。
3. 只读修饰符
属性不能被修改。
public readonly firstName: string;
4. 存取器
通过getter、setter截取对类成员的读写访问。
class GrandSon extends Son {
constructor(firstName: string) {
super(firstName);
}
get myLastName() {
return this.lastName;
}
set myLastName(name: string) {
if (this.firstName === 'Tony') {
this.lastName = name;
} else {
console.error('Unable to change myLastName');
}
}
}
5. 静态属性
定义类的属性和方法
class MyArray {
static displayName = 'MyArray';
static isArray(obj: unknown) {
return Object.prototype.toString.call(obj).slice(8, -1) === 'Array';
}
}
console.log(MyArray.displayName); // => "MyArray"
console.log(MyArray.isArray([])); // => true
console.log(MyArray.isArray({})); // => false
6. 抽象类
不能被实例化仅能被子类继承的特殊类。
abstract class Animal {
}
类的类型
申明函数,就定义了一个特殊的类型,类类型。这个类型的成员就是处了构造函数之前的属性、方法。