TypeScript中的class
在ES6中 Javascript迎来了 class
, 虽然它只是原型链的一种变种写法.它也很大的改变了Javascript世界中的编码方式.Typescript的class
完全兼容ES6中的class
, 并提供了一些特殊的能力.
基础概念介绍
虽然 JavaScript 中有类的概念,但是可能大多数 JavaScript 程序员并不是非常熟悉类,这里对类相关的概念做一个简单的介绍。
- 类(Class):定义了一件事物的抽象特点,包含它的属性和方法
- 对象(Object):类的实例,通过
new
生成 - 面向对象(OOP)的三大特性:封装、继承、多态
- 封装(Encapsulation):将对数据的操作细节隐藏起来,只暴露对外的接口。外界调用端不需要(也不可能)知道细节,就能通过对外提供的接口来访问该对象,同时也保证了外界无法任意更改对象内部的数据
- 继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
- 多态(Polymorphism):由继承而产生了相关的不同的类,对同一个方法可以有不同的响应。比如
Cat
和Dog
都继承自Animal
,但是分别实现了自己的eat
方法。此时针对某一个实例,我们无需了解它是Cat
还是Dog
,就可以直接调用eat
方法,程序会自动判断出来应该如何执行eat
- 存取器(getter & setter):用以改变属性的读取和赋值行为
- 修饰符(Modifiers):修饰符是一些关键字,用于限定成员或类型的性质。比如
public
表示公有属性或方法 - 抽象类(Abstract Class):抽象类是供其他类继承的基类,抽象类不允许被实例化。抽象类中的抽象方法必须在子类中被实现
- 接口(Interfaces):不同类之间公有的属性或方法,可以抽象成一个接口。接口可以被类实现(implements)。一个类只能继承自另一个类,但是可以实现多个接口
类的定义
1 | class Animal { |
class
关键字定义类名,首字母推荐大写.
constructor
是类的构造器,在实例化类的时候自动调用该方法.
在类体中可以定义,类的属性(name
)和方法(sayHi
)
类的继承
1 | class Cat extends Animal { |
使用 extends
关键字实现继承,子类中使用 super
关键字来调用父类的构造函数和方法。
Typescript中一个类只能继承一个父类.
子类包含了一个构造函数,它必须调用super()
,它会执行基类的构造函数。 而且,在构造函数里访问this
的属性之前,我们一定要调用super()
。 这个是TypeScript强制执行的一条重要规则。
静态
TypeScript 的类支持 static
属性,这会被所有这个类的实例共享。一个自然的地方来放置(和访问)它们就是类本身
1 | class Animal { |
你可以定义静态的方法和属性.它们是直接通过类名来方法调用,这些静态方法和属性是所有该类实例共享的.
存取器
TypeScript支持通过getters/setters来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。
1 | class Animal { |
get
和set
在前端架构设计中会非常有用.
访问修饰符
TypeScript 支持访问修饰符 public
、private
和 protected
,它们决定了一个 class
成员的可访问性,如下所示:
可访问在 | public |
protected |
private |
---|---|---|---|
类 | 是 | 是 | 是 |
类的孩子 | 是 | 是 | 否 |
类的实例 | 是 | 否 | 否 |
如果访问修饰符没有被指定,那么它就为 public
,以最接近于 JavaScript 的原生意义 。
1 | class Animal { |
上面👆的例子中,name
被设置为了 public
,所以直接访问实例的 name
属性是允许的。
很多时候,我们希望有的属性是无法直接存取的,这时候就可以用 private
了:
1 | class Animal { |
⚠️需要注意的是,TypeScript 编译之后的代码中,并没有限制 private
属性在外部的可访问性。
上面的例子编译后的代码是:
1 | var Animal = (function () { |
使用 private
修饰的属性或方法,在子类中也是不允许访问的
private
当构造函数修饰为 private
时,该类不允许被继承或者实例化:
1 | class Animal { |
protected
protected
修饰符与private
修饰符的行为很相似,但有一点不同,protected
成员在派生类中仍然可以访问。
1 | class Animal { |
当构造函数修饰为 protected
时,该类只允许被继承:
1 | class Animal { |
抽象类
abstract
可以看成一个访问修饰符。它可以在 class
上也可以在类的成员上。拥有一个 abstract
修饰符主要意味着这个功能不能直接被调用而子类必须提供它。
abstract
的类不能直接被实例化。用户必须创造一些class
来继承abstract class
。abstract
的成员不能直接被访问,而且子类必须提供这个功能。
1 | abstract class Animal { |
抽象类中的抽象方法必须被子类实现:
1 | abstract class Animal { |
参数属性
有的时候我们需要给一个属性在实例化的时候立刻赋值.参数属性可以方便地让我们在一个地方定义并初始化一个成员。
1 | class Animal { |
readonly
只读属性关键字,只允许出现在属性声明或索引签名或构造函数中。
1 | class Animal { |
注意如果 readonly
和其他访问修饰符同时存在的话,需要写在其后面。
1 | class Animal { |
单例模式
1 | class Singleton { |
作者: Fynn
链接: https://fynn90.github.io/2017/05/10/Typescript%E4%B8%AD%E7%9A%84class/
本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可