Appearance
class
TS 中 class 的特点
typescript
class Dog {
constructor(name: string) {
this.name = name;
}
name: string;
run() {}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
typescript
console.log(Dog.prototype);
// {run: ƒ, constructor: ƒ}
/*
打印出类的原型,
结果是不包含类的成员的, 只有 run(), constructor()
*/
1
2
3
4
5
6
7
2
3
4
5
6
7
成员属性只在实例上, 而不在原型上
typescript
let dog = new Dog("大黄");
console.log(dog);
// Dog {name: "大黄"}
/*
可以看出name属性只在实例上, 而不在原型上
*/
1
2
3
4
5
6
7
2
3
4
5
6
7
实例的属性必须具有初始值,或者在构造函数中被初始化
typescript
let dog = new Dog("大黄");
console.log(dog);
// Dog {name: "大黄"}
/*
可以看出name属性只在实例上, 而不在原型上
*/
1
2
3
4
5
6
7
2
3
4
5
6
7
实例的属性必须具有初始值,或者在构造函数中被初始化
typescript
class Dog1 {
constructor(name: string) {
// this.name = name;
}
// 错误提示: 属性“name”没有初始化表达式,且未在构造函数中明确赋值。ts(2564)
name: string;
run() {}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
解决
typescript
class Dog1 {
constructor(name: string) {
// this.name = name;
}
name: string = "dog";
run() {}
}
// 或者
class Dog2 {
constructor(name: string) {
this.name = name;
}
name: string;
run() {}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
类的继承
typescript
class Cat0 extends Dog {
//错误提示: 派生类的构造函数必须包含 "super" 调用。ts(2377)
constructor() {}
}
1
2
3
4
2
3
4
解决 super 代表父类的实例
typescript
class Cat extends Dog {
constructor(name: string, color: string) {
super(name);
this.color = color;
}
color: string;
}
1
2
3
4
5
6
7
2
3
4
5
6
7
类的成员修饰符
共有成员 -public
类的所有属性默认都是 public,当然也可以直接申明出来
typescript
class Dog1 {
constructor(name: string) {
// this.name = name;
}
public name: string = "dog";
run() {}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
私有成员 -private
私有成员只能被类本身调用,而不能被类的实例调用,有不能被子类调用
typescript
class Dog {
constructor(name: string) {
this.name = name;
}
public name: string;
run() {}
private walk() {}
}
let dog = new Dog("大黄");
// 错误提示: 属性“walk”为私有属性,只能在类“Dog”中访问。ts(2341)
dog.walk();
class Cat extends Dog {
constructor(name: string, color: string) {
super(name);
this.color = color;
// 错误提示: 属性“walk”为私有属性,只能在类“Dog”中访问。ts(2341)
this.walk = () => {};
}
color: string;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
可以给构造函数添加私有成员属性,表示该类既不能被实例化,也不能被继承
typescript
class Dog {
private constructor(name: string) {
this.name = name;
}
public name: string;
run() {}
private walk() {}
}
// 错误提示: 类“Dog”的构造函数是私有的,仅可在类声明中访问。ts(2673)
let dog = new Dog("大黄");
// 错误提示: 无法扩展类“Dog”。类构造函数标记为私有。ts(2675)
class Cat extends Dog {
constructor(name: string, color: string) {
super(name);
this.color = color;
}
color: string;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
受保护成员 -protect
受保护成员只能在类及其子类中访问, 而不能再类的实例中访问
typescript
class Dog {
constructor(name: string) {
this.name = name;
}
public name: string;
protected shout() {}
}
let dog = new Dog("大黄");
// 错误提示: 属性“shout”受保护,只能在类“Dog”及其子类中访问。ts(2445)
dog.shout();
class Cat extends Dog {
constructor(name: string, color: string) {
super(name);
this.color = color;
// 可以正常访问和执行
this.shout();
}
color: string;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
可以给构造函数添加受保护成员属性,表示该类不能被实例化,只能被继承,相当于申明一个基类
只读属性
只读属性表示不能被更改,并且一定要被初始化
typescript
class Dog {
constructor(name: string) {
this.name = name;
}
public name: string;
readonly foots: number = 4;
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
静态成员 -static
类的静态成员只能通过类名来调用,二不能通过子类调用
typescript
class Dog {
constructor(name: string) {
this.name = name;
}
public name: string;
static food = "bones";
}
let dog = new Dog("大黄");
// bones
console.log(Dog.food);
// 错误提示: 属性 "food" 不是类型为 "Dog" 的静态成员ts(2576)
console.log(dog.food);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
类的静态成员也可以被继承
typescript
class Dog {
constructor(name: string) {
this.name = name;
}
public name: string;
static food = "bones";
}
class Cat extends Dog {
constructor(name: string, color: string) {
super(name);
this.color = color;
}
color: string;
}
// bones
console.log("Cat.food :", Cat.food);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ES 中并没有抽象类的概念,TS 对此进行了扩展
抽象类
抽象类:只能被继承,不能被实例化的类
typescript
abstract class Animal {
constructor() {}
}
// 无法创建抽象类的实例。ts(2511)
let animal = new Animal();
1
2
3
4
5
2
3
4
5
可以在抽象类中定义一个具体的方法并有相关实现 这样子类就可以直接使用,而不用重复实现 --- 实现了方法的复用
typescript
abstract class Animal {
constructor() {}
eat() {
console.log("eat");
}
}
class Pig extends Animal {
constructor(name: string) {
super();
this.name = name;
}
public name: string;
static food = "bones";
}
let pig = new Pig("佩奇");
pig.eat();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
多态
可以在抽象类中定义一个方法但不具体实现,形成一个抽象方法。抽象方法的好处是可以在子类中有多种方式实现,
typescript
abstract class Animal {
constructor() {}
abstract sleep(): void;
}
class Pig extends Animal {
constructor(name: string) {
super();
this.name = name;
}
public name: string;
sleep() {
console.log("站着睡");
}
}
let pig = new Pig("佩奇");
pig.sleep();
class Cat extends Animal {
sleep() {
console.log("趴着睡");
}
}
let cat = new Cat();
cat.sleep();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
特殊的 TS 类型:this 类型
类的成员方法可以直接返回一个 this, 这样就可以很方便的实现链式调用
typescript
class WorkFlow {
step1() {
return this;
}
step2() {
return this;
}
}
let workFlow = new WorkFlow();
workFlow.step1().step2();
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
在继承的时候,this 也可以表现出多态 (this 既可以是父类型,也可以是子类型)
typescript
class WorkFlow {
step1() {
return this;
}
step2() {
return this;
}
}
let workFlow = new WorkFlow();
workFlow.step1().step2();
class MyFlow extends WorkFlow {
next() {
return this;
}
}
let myflow = new MyFlow();
// myflow.next(): MyFlow {}
console.log("myflow.next(): ", myflow.next());
// myflow.next().step1(): MyFlow {}
console.log("myflow.next().step1(): ", myflow.next().step1().next().step2());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26