本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-09-24
new
生成。public
表示公有属性或方法。implements
,一个类只能继承自另一个类,但是可以实现多个接口。class Cat extends Animal {
constructor(name) {
super(name); // 调用父类的 constructor(name)
console.log(this.name);
}
sayHi() {
return 'Meow, ' + super.sayHi(); // 调用父类的 sayHi()
}
}
使用 getter
和 setter
改变属性的赋值和读取行为。
class Animal {
constructor(name) {
this.name = name;
}
get name() {
return 'Jack';
}
set name(value) {
console.log('setter: ' + value);
}
}
class Animal {
static isAnimal(a) {
return a instanceof Animal;
}
}
let a = new Animal('Jack');
Animal.isAnimal(a); // true
a.isAnimal(a); // TypeError: a.isAnimal is not a function”
可以直接在类中定义实例属性并给初始值,如果没有给初始值,只是声明了name: string
, 那么一定要在构造函数中给初始值。
class Animal {
// ES6中的实例属性只能在构造函数中使用 `this.xxx` 来定义,ES7中可以直接在类中定义并给初始值
name = 'Jack';
constructor() {
// ...
}
}
let a = new Animal();
console.log(a.name); // Jack
class Animal {
static num = 42;
constructor() {
// ...
}
}
console.log(Animal.num); // 42
TypeScript中修饰符也分为三种:
public
:修饰的属性和方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是公有的。private
:修饰的属性和方法是私有的,不能在声明它的类的外部访问。protected
:修饰的属性和方法是受保护的,它和 private
类似,区别是它在子类中也是允许被访问的。需要注意的是,实际上,修饰符修饰的属性都是实例属性,即一切定义在类中的属性,除了 static
修饰的都是实例属性。
相关示例:
1、编译时:不能在实例上访问私有属性
class Animal {
private name;
public constructor(name: string) {
this.name = name;
}
}
let a = new Animal('Jack');
console.log(a.name);
// 编译报错: 属性“name”为私有属性,只能在类“Animal”中访问。
需要注意的是,TypeScript编译之后的代码中,并没有限制 private
属性在外部的可访问性,上面的代码依然能正常打印出 'Jack'
,编译后如下:
"use strict";
class Animal {
constructor(name) {
this.name = name;
}
}
let a = new Animal('Jack');
// console.log(a.name);
2、编译时:不能在子类中访问父类私有属性
class Cat extends Animal {
constructor(name: string) {
super(name)
console.log(this.name);
// 子类自己没有name属性,则访问父类的
// 编译报错: 属性“name”为私有属性,只能在类“Animal”中访问。
}
}
3、编译时:可以在子类中访问 protected
修饰的属性,但是不能在实例上访问
class Animal {
protected name;
constructor(name: string) {
this.name = name;
}
}
let a = new Animal('Jack');
console.log(a.name); // 编译报错,属性“name”受保护,只能在类“Animal”及其子类中访问。
class Cat extends Animal {
constructor(name: string) {
super(name)
console.log(this.name); // 通过编译
}
}
4、当构造函数修饰符为 private
时,该类不允许被继承或者实例化:
class Animal {
public name;
private constructor(name: string) {
this.name = name;
}
}
let a = new Animal('Jack'); // Error 类“Animal”的构造函数是私有的,仅可在类声明中访问。
class Cat extends Animal { // Error 无法扩展类“Animal”。类构造函数标记为私有。
constructor(name: string) {
super(name);
}
}
5、当构造函数修饰符为 protected
时,该类可以被继承,但是不能实例化
class Animal {
public name;
protected constructor(name: string) {
this.name = name;
}
}
let a = new Animal('Jack'); // Error 类“Animal”的构造函数是受保护的,仅可在类声明中访问。
class Cat extends Animal { // 通过编译
constructor(name: string) {
super(name);
}
}
修饰符和readonly
可以使用在构造函数参数中,等同于在类中定义该属性同时给该属性赋值
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
}
// 等同于, 使代码更简洁
class Animal {
constructor(public name: string) {}
}
只读属性关键字,只允许出现在属性声明或索引签名或构造函数参数中。
class Animal {
readonly name: string;
constructor(name: string) {
this.name = name;
}
}
let a = new Animal('jack')
console.log(a.name); // jack
a.name = 'tom'; // error 无法分配到 "name" ,因为它是只读属性。
注意如果 readonly
和其他访问修饰符同时存在的话,需要写在其后面:
class Animal {
public readonly name: string
public constructor(name: string) {
this.name = name;
}
}
abstract
用于定义抽象类和其中的抽象方法(抽象方法只能出现在抽象类中),什么是抽象类?首先,抽象类是不允许被实例化;其次,抽象类的方法必须由子类实现。
abstract class Animal {
public name;
public constructor(name: string) {
this.name = name;
}
public abstract sayHi(): void;
}
let a = new Animal('jack') // error 无法创建抽象类的实例。
class Cat extends Animal { // error 非抽象类“Cat”不会实现继承自“Animal”类的抽象成员“sayHi”。
public eat() {
console.log(`${this.name} is eating.`);
}
}
let cat = new Cat('Tom');
需要注意的是,抽象类中的抽象方法是不会编译的,而只定义eat
方法,编译报错,最终编译结果还是会包含 eat
方法。