# 五.类
前言
# 1.ts 中定义类
class Pointer {
x!: number; //实例上的属性必须先声明
y!: number;
constructor(x: number, y?: number, ...args: number[]) {
this.x = x;
this.y = y as number;
}
}
let p = new Pointer(100, 200);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
实例上的属性需要先声明再使用,构造函数中的参数可以使用可选参数和剩余参数
# 2.类中的修饰符
public
修饰符(谁都可以访问到)
class Animal {
public name!: string; //不写public默认也是公开的
public age!: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
console.log(this.name, this.age); //子类访问
}
}
let p = new Cat("Tom", 18);
console.log(p.name, p.age); //外层访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Animal {
constructor(public name: string, public age: number) {
this.name = name;
this.age = age;
}
}
1
2
3
4
5
6
2
3
4
5
6
我们可以通过参数属性来简化父类中的代码
protected
修饰符(自己和子类可以访问到)
class Animal {
constructor(protected name: string, protected age: number) {
this.name = name;
this.age = age;
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
console.log(this.name, this.age);
}
}
let p = new Cat("Tom", 18);
console.log(p.name, p.age); //无法访问
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
private
修饰符(除了自己都访问不到)
class Animal {
constructor(private name: string, private age: number) {
this.name = name;
this.age = age;
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
console.log(this.name, this.age); //无法访问
}
}
let p = new Cat("Tom", 18);
console.log(p.name, p.age); //无法访问
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
readonly
修饰符(仅读修饰符)
class Animal{
constructor(public readonly name:string,public age:number){
this.name= name
this.age = age
}
changeName(name:string){
this.name = name://仅读属性只能在constructor中被赋值
}
}
class Cat extends Animal{
constructor(name:string,age:number){
super(name,age)
}
}
let p = new Cat('Tom',18)
p.changeName('Jerry')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
静态属性和静态方法是可以被子类所继承的
# 4.Super 属性
class Animal {
say(message: string) {
console.log(message);
}
static getType() {
return "动物";
}
}
class Cat extends Animal {
say() {
//原型方法中的super指代的是父类的原型
super.say("喵喵叫");
}
static getType() {
//静态方法中的super指代的是父类
return super.getType();
}
}
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
# 5.类的装饰器
# 5.1 装饰类
function addSay(target: any) {
target.prototype.say = function () {
console.log("say");
};
}
@addSay
class Person {
say!: Function;
}
let person = new Person();
person.say();
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
装饰类可以给类扩展功能,需要开启experimentalDecorators:true
# 5.2 装饰类中属性
function toUpperCase(target: any, key: string) {
let value = target[key];
Object.defineProperty(target.key, {
get() {
return value.toUpperCase();
},
set(newValue) {
value = newValue;
},
});
}
function double(target: any, key: string) {
let value = target[key];
Object.defineProperty(target, key, {
get() {
return value * 2;
},
set(newValue) {
value = newValue;
},
});
}
class Person {
@toUpperCase
name: string = "xiaomin";
@double
static age: number = 10;
getName() {
return this.name;
}
}
let person = new Person();
console.log(person.getName(), Person.age);
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
30
31
32
33
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
30
31
32
33
装饰属性可以对属性的内容进行改写,装饰的是实例属性则 target 指向类的原型、装饰的是静态属性则 target 执行类本身
# 5.3 装饰类中方法
function noEnum(target: any, key: string, descriptor: PropertyDescriptor) {
console.log(descriptor);
descriptor.enumerable = false;
}
class Person {
@toUpperCase
name: string = "xiaomin";
@double
static age: number = 10;
@noEnum
getName() {
return this.name;
}
}
let person = new Person();
console.log(person); // getName 不可枚举
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 5.4 装饰参数
function addPrefix(target: any, key: string, paramIndex: number) {
console.log(target, key, paramIndex);
}
class Person {
@toUpperCase
name: string = "JiangWen";
@double
static age: number = 10;
prefix!: string;
@noEnum
getName(@addPrefix prefix: string) {
return this.name;
}
}
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
# 6.抽象类
抽象类无法被实例化,只能被继承,抽象方法不能在抽象类中实现,只能在抽象类的具体子类中实现,而且必须实现
abstract class Animal {
name!: string;
abstract speak(): void;
}
class Cat extends Animal {
speak() {
console.log("abc");
}
}
class Dog extends Animal {
speak(): string {
console.log("3333");
return "dsfasd";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
定义类型时void
表示函数的返回值为空(不关心返回值类型,所以在定义函数时也不关心函数返回值类型)