面向对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class 类名 {

/* 静态属性 */
static 属性: 类型 = 属性值;
/* 实例属性 */
属性: 类型 = 属性值;
/* 只读属性 */
readonly 属性: 类型 = 属性值;
static readonly 属性: 类型 = 属性值;

constructor(参数: 类型) {
this.属性 = 参数;
}

/* 静态方法 */
static 方法名() {}

/* 实例方法 */
方法名() {}

}

constructor 就是构造器,用来给实例属性赋值,在实例化对象时会被调用
构造器中的 this 指向实例化对象
类名首字母必须大写

静态属性不需要实例化对象,使用类名直接使用
实例属性需要实例化对象进行调用
只读属性只能调用,不能修改

方法中的 this 指向调用的对象

继承

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
class Father {
name: string;
age: number;

constructor(name: string, age: number) {
this.name = name;
this.age = age;
}

run() {
console.log(' running');
}
}
class Son extends Father {
weight: number;

constructor(name: string, age: number, weight: number) {
super(name, age);
this.weight = weight;
}

run() {
console.log(this.name + 'running');
}

say() {
console.log('borning');
}
}

let son = new Son('son', 18, 70);
son.run();
son.say();

子类继承父类,使用 extends 关键字
子类继承父类以后,可以使用父类的属性和方法
子类可以重写父类的方法(重写即方法名相同,方法体不同)
子类重写父类方法,并不会影响父类中的方法

子类自定义的属性和方法是不能被父类调用的

子类中的 super 表示父类
super() 表示父类的构造器,需要写在子类构造器的第一行

抽象类

抽象类不能用来创建对象,专门用来继承的

1
2
3
abstract class Father {
abstract run(): void;
}

以 abstract 开头的类就是抽象类
抽象类中可以定义抽象方法

抽象方法以 abstract 开头,并且没有方法体
抽象方法只能定义在抽象类中,继承的子类必须重写抽象方法

接口

接口就是用来定义类的结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
interface myInterface {
name: string;
age: number;

run(): void;
}

class myClass implements myInterface {
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}

run(): void{
console.log('running')
}
}

let human = new myClass('张三', 30);
human.run();

接口中的所有属性都没有实际的值,需要类实现来赋值
接口中的所有方法都没有方法体,需要类实现来重写c

类需要使用 implements 来实现接口

1
2
3
4
5
6
interface myInterface {
name: string;
age: number;
}

let obj: myInterface;

接口也可以当作类型声明来使用

属性封装

提高数据的安全性

变量修饰符

  • public:公共的,可以任意修改,默认值
  • private:私有的,只能在类内部进行修改
  • protected:受保护的,只能在当前类或当前类子类访问

封装

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
class myClass {
_name: string;
_age: number;

setName(value: string) {
this._name = value;
}
getName(){
return this._name;
}
setAge(value: number) {
this._age = value;
}
getAge() {
return this._age;
}
}

let item = new myClass()

/* 设置 name 属性值 */
item.setName('张三');
/* 设置 age 属性值 */
item.setAge(20);

/* 获取 name 属性值 */
item.getName();
/* 获取 age 属性值 */
item.getAge()

getName 和 setName 方法都是存取器
实例对象不能直接调用属性,可以保证数据的安全性

通过 getName 方法获取 name 属性值;通过 setName 方法设置 name 属性值

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
class myClass {
_name: string;
_age: number;

set name(value: string) {
this._name = value;
}
get name(){
return this._name;
}
set age(value: number) {
this._age = value;
}
get age() {
return this._age;
}
}

let item = new myClass();
/* 设置 name 属性值 */
item.name = '张三';
/* 设置 age 属性值 */
item.age = 20;

/* 获取 name 属性值 */
console.log(item.name);
/* 获取 age 属性值 */
console.log(item.age);

TS 提高了更加简单的方法
get 和 set 方法都是存取器
item.name 实质是调用 get 和 set 方法