# 定义
类(英语: class
)在面向对象编程(oop) (opens new window)中是一种面向对象计算机编程语言的构造, 是创建对象的蓝图, 描述了所创建的对象共同的属性和方法。
JavaScript
语言中, 生成实例对象的传统方法是通过构造函数。ES6
提供了更接近传统语言的写法, 引入了 Class(类)
这个概念, 作为对象的模板。通过 class
关键字, 可以定义类。
TypeScript
除了实现了所有 ES6
中的类的功能以外,还添加了一些新的用法。
# 类的概念
对象
类的实例, 通过
new
实例化-
👇👇👇 Here
-
getter
: 对属性的取值行为setter
: 对属性的赋值行为 -
public
: 修饰公有属性和方法(默认)
,可以在任何地方被访问到protected
: 修饰保护属性和方法,在子类中也是允许被访问的private
: 修饰私有属性和方法,不能在声明它的类的外部访问 -
只能通过类访问的属性
or
方法。 -
抽象类
(absctract)
是供其他类继承的基类,抽象类不允许被实例化。抽象类中的抽象方法必须在子类中被实现 -
不同类之间公有的属性或方法,可以抽象成一个接口。接口可以被类实现
(implements)
。一个类只能继承自另一个类,但是可以实现多个接口
# 面向对象的三大特性
# 封装
利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。
# 继承
子类获取父类的所有属性和行为(除了父类中用 private 修饰的变量和方法)
。
# 多态
多种不同的实现方式即为多态, 它允许方法重名,参数或返回值可以是父类型传入或返回。
# 类的好处
对象提供了模型化和信息隐藏的好处。
类提供了可重复使用性 (opens new window)的好处。
# 使用
# public(公有) & protected(保护) & private(私有) 修饰符
# public
修饰公有属性和方法 (默认)
,可以在任何地方被访问到
class Animal {
public name: string;
public constructor(theName: string) { this.name = theName; }
public move(distanceInMeters: number) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
2
3
4
5
6
7
# protected
修饰保护属性和方法,在子类中也是允许被访问的
class Person {
protected name: string;
constructor(name: string) { this.name = name; }
}
class Employee extends Person {
private department: string;
constructor(name: string, department: string) {
super(name)
this.department = department;
}
public getElevatorPitch() {
return `Hello, my name is ${this.name} and I work in ${this.department}.`;
}
}
let rainy = new Employee("Rain", "120");
console.log(rainy.getElevatorPitch());
console.log(rainy.name); // 错误
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# private
修饰私有属性和方法,不能在声明它的类的外部访问
class Animal {
private name: string;
constructor(theName: string) { this.name = theName; }
}
class Cat extends Animal {
constructor() { super("Cat"); }
}
class Employee {
private name: string;
constructor(theName: string) { this.name = theName; }
}
let animal = new Animal("Dog");
let cat = new Cat();
let employee = new Employee("Rain120");
animal = cat;
animal = employee; // 错误: Animal 与 Employee 不兼容.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# readonly 修饰符
# 属性
将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。
class Octopus {
readonly name: string;
readonly numberOfLegs: number = 8;
constructor (theName: string) {
this.name = theName;
}
}
let dad = new Octopus("Man with the 8 strong legs");
dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.
2
3
4
5
6
7
8
9
# 参数
class Octopus {
readonly numberOfLegs: number = 8;
constructor(readonly name: string) {
}
}
2
3
4
5
# 存取器
class Employee {
private _fullName: string = '';
constructor(_fullName: string) {}
get fullName(): string {
return this._fullName;
}
set fullName(newName: string) {
this._fullName = newName;
}
}
let employee = new Employee('Rainy');
employee.fullName = "Rain120";
console.log(employee.fullName)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Note:
- 存取器要求你将编译器设置为输出
ECMAScript 5
或更高。 不支持降级到ECMAScript 3
。 - 只带有
get
不带有set
的存取器自动被推断为readonly
。 这在从代码生成.d.ts
文件时是有帮助的,因为利用这个属性的用户会看到不允许够改变它的值。
# 静态属性 & 方法
只能通过类来访问,实例不行
class Boy {
static handsome: boolean = true;
constructor(public name: string) {}
static isHandsome() {
return this.handsome;
}
}
let rain120 = new Boy('Rain120');
console.log(Boy.handsome);
console.log(Boy.isHandsome);
console.log(rain120.handsome); // Property 'handsome' is a static member of type 'Boy'
console.log(rain120.isHandsome); // Property 'isHandsome' is a static member of type 'Boy'
2
3
4
5
6
7
8
9
10
11
12
13
# 继承
class Boy {
handsome: boolean;
name: string;
constructor(name: string, handsome: boolean) {
this.name = name;
this.handsome = handsome;
}
isHandsome() {}
}
class Mine extends Boy {
isHandsome() {
return this.handsome;
}
}
const mine = new Mine('Rain120', true);
console.log(mine)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 多态
export function trace(cities: any, prop?: string, enterBreakPoint?: boolean): void;
export function trace(cities: any, enterBreakPoint?: boolean): void;
export function trace(enterBreakPoint?: boolean): void;
export function trace(...args: any[]): void {
}
2
3
4
5
6
7
8
# 抽象类
abstract class Boy {
handsome: boolean;
name: string;
constructor(name: string, handsome: boolean) {
this.name = name;
this.handsome = handsome;
}
abstract isHandsome(): boolean;
}
class Mine extends Boy {
isHandsome() {
return this.handsome;
}
}
const mine = new Mine('Rain120', true);
console.log(mine);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 把类当接口使用
class Boy {
handsome: boolean = true;
}
class Girl {
beatiful: boolean = true;
}
enum Gender {
'MALE',
'FEMALE'
}
interface Person extends Boy, Girl {
gender: Gender;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 快来耍耍啊
# 🌰🌰
// template
# 游乐场
# 参考答案
// answer
# 参考资料
handbook - classes (opens new window)
深入理解 TypeScript - 类 (opens new window)