ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] >[success] # class - 类 初次见面 大家都清楚,在 **javascript 的世界** 都是用 **原型链** 与 **构造函数** 来实现 **继承** ,到了 **ES6** 时代,总算出现了 **Class** 的概念, **虽然它内部还是原型链的机制来实现**,但是我们总算有了新的方法,从我们熟悉的 **面向对象** 的方式来审视这门语言了,**Typescript** 对 **类的支持更加丰富,除了ES6、ES7有的内容,还添加了新的内容** ,首先我们来复习一下 **Class** : 1. **类(Class):定义了一切事物的抽象特点** **定义了一切事物的抽象特点** ,包括它的 **属性** 和 **方法** , 假如说 **它就是一张汽车的图纸,上面描绘了如何制作汽车** 2. **对象(Object):类的实例** 我们可以说 **一辆宝马车是实例,一个奥迪车也是一个实例** 。 3. **面向对象(OOP)三大特性:封装、继承、多态** 1. **封装** **封装** ,就是说对 **数据操作的细节隐藏起来,只暴露对外的接口,外界调用端不需要,也可能不知道里面的细节,只能通过对外提供的接口来访问该对象。** **** 2. **继承** **继承** 很好理解, **子类** 可以 **继承父类** ,**子类除了拥有父类所有的特征外,还有一些更具体的特性。** **** 3. **多态** 由 **继承** 产生了相关 **不同的类** ,对 **同一个方法可以有不同的响应,比如猫跟狗,都继承自 animal(动物) 它们都继承了自己 eat(吃) 的方法,此时针对某一个实例,我们无需了解它是猫或狗,我们可以直接调用 eat 这个方法,程序会自动判断出来应该如何执行这个方法** 接下来我们根据上面讲解的意思,来写这么一个类 **class.js** ~~~ // ---------------------------------------- 1. 封装 ----------------------------- // 基本类(动物基类) class Animal { constructor(name){ this.name = name } run(){ return `${this.name} 在奔跑` } } // 实例化函数 // const snake = new Animal('小狗') // console.log(snake.run()) // ---------------------------------------- 2. 继承 ----------------------------- // 小狗继承动物这个类(派生类) class Dog extends Animal { bark(){ return `${this.name} 在狂吠` } } // 小狗继承了动物这个类的方法 const xiaobao = new Dog('旺财') console.log(xiaobao.run()) console.log(xiaobao.bark()) // ---------------------------------------- 3. 多态 ----------------------------- // 小猫继承动物这个类(派生类) class Cat extends Animal { // 静态方法 static categories = ['mammal'] constructor(name){ // 使用父类的属性,ES6中我们可以通过类,我们使用extends实现基类(SuperType)与派生类(SubType)之间的继承。在派生类的constructor中调用super()即可访问基类的构造函数。super()负责初始化this,相当于ES5中的call和apply方法。 super(name) console.log(this.name) } run(){ // 方法重写 // 调用父类方法 return `喵, ${super.run()}` } } const maomao = new Cat('小臭猫') console.log(maomao.run()) // 静态属性与方法,不需要new实例化,可以直接调用 console.log(Cat.categories) ~~~ 为什么要有 **静态属性** 或 **静态方法**呢,因为 **Class 类里面的定义和实例状态没有太大的关系 。** >[success] ## Typescript 中的类 **Typescript** 中增强了 **Class 类** ,分别是 **Public、 Private、 Protected、 readonly** ,有了这 **4 种修饰符** ,我们就可以 **给类上的方法和属性提供权限管理** ,因为 **有些内容,我们是不愿意暴露给外部使用的** 。 * **Public** : **修饰的属性或方法是共有的,默认使用的属性或方法都是Public** * **Private** : **修饰的属性或方法是私有的,不能在声明它的类的外部调用** * **Protected** : **修饰的属性或方法是受保护的,它跟 Private 类似,因为它在子类中是允许被访问的** * **readonly** : **只读属性,只可以读取,不可以修改** 1. **Public** **Public** 就没有什么可以讲的了,因为默认就是 **Public** 2. **Private** 下面的 **run 函数** 前面添加了 **private 修饰符** **class.ts** ~~~ // 基本类(动物基类) class Animal { name: string; constructor(name){ this.name = name } private run(){ return `${this.name} 在奔跑` } } // 实例化函数 const snake = new Animal('小狗') console.log(snake.run()) ~~~ 如下,执行时就会报错,加了 **private 修饰符** ,就变成了 **私有方法** ,外部不可以访问。 ![](https://img.kancloud.cn/2e/b9/2eb998f19f83a08a93d9f18efe35560d_864x410.png) 3. **protected** **protected 有点像遗产,只有我与我的子女可以访问,其他外部人员都不可以访问** **class.ts** ~~~ // ---------------------------------------- 1. 封装 ----------------------------- // 基本类(动物基类) class Animal { name: string; constructor(name){ this.name = name } protected run(){ return `${this.name} 在奔跑` } } // 实例化函数 const snake = new Animal('小狗') console.log(snake.run()) // ---------------------------------------- 2. 继承 ----------------------------- // 小狗继承动物这个类(派生类) class Dog extends Animal { bark(){ return `${this.name} 在狂吠` } } // 小狗继承了动物这个类的方法 const xiaobao = new Dog('旺财') console.log(xiaobao.run()) console.log(xiaobao.bark()) // ---------------------------------------- 3. 多态 ----------------------------- // 小猫继承动物这个类(派生类) class Cat extends Animal { // 静态方法 static categories = ['mammal'] constructor(name){ // 使用父类的属性,ES6中我们可以通过类,我们使用extends实现基类(SuperType)与派生类(SubType)之间的继承。在派生类的constructor中调用super()即可访问基类的构造函数。super()负责初始化this,相当于ES5中的call和apply方法。 super(name) console.log(this.name) } run(){ // 方法重写 // 调用父类方法 return `喵, ${super.run()}` } } const maomao = new Cat('小臭猫') console.log(maomao.run()) // 静态属性与方法,不需要new实例化,可以直接调用 console.log(Cat.categories) ~~~ 4. **readonly** 有些时候我们希望有些 **属性只能读取不可以修改** ,这时候我们可以使用 **readonly 修饰符** **class.ts** ~~~ // 基本类(动物基类) class Animal { readonly name: string; constructor(name){ this.name = name } protected run(){ return `${this.name} 在奔跑` } } // 实例化函数 const snake = new Animal('小狗') snake.name = '小明' console.log(snake.run()) ~~~ **修改 name** 就会报错 ![](https://img.kancloud.cn/97/96/9796d4f457a1d280a3c16ed7b1c4d059_632x395.png)