传统的面向对象语言基本都是基于类的,JavaScript基于原型的方式让开发者多了很多理解成本,在es6以后,JavaScript拥有了class关键字,虽然本质依然是构造函数,但是开发者已经可以比较舒服的使用class了。
JavaScript的class依然有一些特性没有加入,比如修饰符和抽象类等。
抽象类
抽象类作为其他派生类的基类使用,它们一般不会直接被实例化,不同于接口,抽象类可以包含成员的实现细节。
abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法。
比如创建一个Animal抽象类:
abstract class Animal {abstract makeSound():void;move():void{console.log('roaming the earth...')}}
若是实例化此抽象类会报错:
我们不能直接实例化抽象类,通常需要我们创建子类继承基类,然后实例化子类。
class Cat extends Animal {makeSound () {console.log("miao miao");}}const cat = new Cat()cat.makeSound() // miao miaocat.move() // roaming the earch...
访问限定符
传统面向对象语言通常都有访问限定符,ts中有三类访问限定符,分别是:public、private、protected。
public
在typescript的类中,成员都默认为public,被此限定符修饰的成员是可以外部访问。
class Car {public run() {console.log('启动。。。')}}const car = new Car()car.run() // 启动。。。
private
当成员被设置为private之后,被此限定符修饰的成员只可以被类的内部访问。
protected
当成员被设置为protected之后,被此限定符修饰的成员是只可以被类的内部以及类的子类访问。
class Car {protected run() {console.log('启动...')}}class GTR extends Car {init() {this.run();}}const car = new Car()const gtr = new GTR()car.run() //[ts]属性“run”受保护,只能在类“Car”及其子类中访问。gtr.init()// 启动...gtr.run() // [ts]属性“run”受保护,只能在类“Car”及其子类中访问。
class可以作为接口
类(class)也可作为接口。
把class作为interface使用,在react工程中是很常用的。
比如这个轮播组件rc-carousel。
export default class Carousel extends React.Component<Props,State>{}
由于组件需要传入props的类型Props,同时,有需要设置默认props即defaultProps。
此时即体现了class作为接口的优势。
我们先声明一个类,这个类包含组件props所需的类型和初始值:
//props的类型export default class Props {public children: Array<React.ReactElement<any>> | React.ReactElement<any> | never[] = []public speed:number = 500public height: number = 160public animation: string = 'easeInputOutQuad'public isAuto: boolean = truepublic autoPlaInterval: number = 4500public afterChange: () => {}public beforeChange: () => {}public selesctedColor: () => {}public selesctedColor: stringpublic showDots: boolean = true}
当我们需要传入props类型的时候直接将Props作为接口传入,此时Props的作用就是接口,而当需要我们设置defaultProps初始值时,我们只需要:
public static defaultProps = new Props()
Props 的实例就是defaultProps的初始值,这就是class作为接口的实际应用,我们用一个class起到了接口和设置初始值两个作用,方便统一管理,减少了代码量。
