【 TypeScript 】对TypeScript中类的理解?应用场景?

1. 是什么

类(Class)是面向对象程序设计(OOP,Object-Oriented Programming)实现信息封装的基础
类是一种用户定义的引用数据类型,也称类类型
传统的面向对象语言基本都是基于类的,JavaScript基于原型的方式让开发者多了很多理解成本在ES6之后,JavaScript拥有了class关键字,虽然本质依然是构造函数,但是使用起来已经方便了许多
但是JavaScript的class依然有一些特性还没有加入,比如修饰符和抽象类TypeScript的class支持面向对象的所有特性,比如类、接口等

2. 使用方式

定义类的关键字为class ,后面紧跟类名,类可以包含以下几个模块(类的数据成员):

  • 字段: 字段是类里面声明的变量。字段表示对象的有关数据。
  • 构造函数: 类实例化时调用,可以为类的对象分配内存。
  • 方法:方法为对象要执行的操作

如下例子:

class Car {
    // 字段
    engine:string;
    // 构造函数
    constructor(engine:string) {
        this.engine = engine
    }
    // 方法
    disp():void {
        console.log(" : "+this.engine)
    }
 }

2.1 继承

类的继承使用extends的关键字

class Animal {
    move(distanceInMeters: number = 0) {
    console.log(`Animal moved ${distanceInMeters}m.`); } 
}
class Dog extends Animal {
    bark() {
        console.log('Woof! Woof!'); 
    } 
}
const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();

Dog是一个派生类,它派生自Animal基类,派生类通常被称作子类,基类通常被称作超类Dog类继承了Animal类,因此实例dog也能够使用Animal类move方法
同样,类继承后,子类可以对父类的方法重新定义,这个过程称之为方法的重写,通过super关键字是对父类的直接引用,该关键字可以引用父类的属性和方法,如下:

class PrinterClass {
  doPrint():void {
    console.log(" 父类方法 ")
  } 
}
class StringPrinter extends PrinterClass {
  doPrint():void {
    super.doPrint() // 调用父类的函数
    console.log(" 子类方法 ") 
  } 
}

2.2 修饰符

可以看到,上述的形式跟ES6十分的相似,typescript在此基础上添加了三种修饰符:

  • 公共public:可以自由的访问类程序里定义的成员
  • 私有private:只能够在该类的内部进行访问
  • 受保护protect:除了在该类的内部可以访问,还可以在子类中仍然可以访问

2.3 私有修饰符

只能够在该类的内部进行访问,实例对象并不能够访问

class Father {
  private name:String
  constructor(name:String){
    this.name =name
  }
}
const father =new Father('superrui')
father.name //报错 属性“name"为私有属性,只能在类“Father”中访问。

并且继承该类的子类并不能访问,如下图所示:

class Father {
    private name:String
    constructor(name:String){
        this.name =name
    }
}

class Son extends Father{
    say(){
      // 报错 属性"name"为私有属性,只能在类“Father”中访问。
        console.log(`my name is ${this.name}`)
    }
}

2.4 受保护的修饰符

跟私有修饰符很相似,实例对象同样不能访问受保护的属性,如下:

class Father{
  protected name:String
  constructor(name:String){
    this.name =name
  }
}
const father =new Father('huihui')
//报错 属性“name“受保护,只能在类“Father”及其子类中访问
father.name

有一点不同的是protected成员在子类中仍然可以访问

class Father {
    protected name:String
    constructor(name:String){
        this.name =name
    }
}

class Son extends Father{
    say(){
      // 可以正常访问name 属性
        console.log(`my name is ${this.name}`)
    }
}

除了上述修饰符之外,还有只读修饰符

2.5 只读修饰符

通过readonly关键字进行声明,只读属性必须在声明时或构造函数里被初始化,如下:

class Father {
  readonly name:String
  constructor(name:String){
    this.name =name
  }
}
const father =new Father('superrui')
father.name //报错 属性“name"为只读属性

2.6 静态属性

这些属性存在于类本身上面而不是类的实例上,通过static进行定义,访问这些属性需要通过类型.静态属性的这

种形式访问,如下所示:
class Square{
  static width='100px'
}
console.log(Square.width) //

上述的类都能发现一个特点就是,都能够被实例化,在typescript中,还存在一种抽象类

2.7 抽象类

抽象类做为其它派生类的基类使用,它们一般不会直接被实例化,不同于接口,抽象类可以包含成员的实现细节
abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法,如下所示:

abstract class Animal {
  abstract makeSound(): void;
  move(): void {
    console.log('roaming the earch...'); 
  } 
}

这种类并不能被实例化,通常需要我们创建子类去继承,如下:

class Cat extends Animal {
  makeSound() {
    console.log('miao miao') 
  }
}
const cat = new Cat()
cat.makeSound() // miao miao
cat.move() // roaming the earch...

3. 应用场景

除了日常借助类的特性完成日常业务代码,还可以将类(class)也可以作为接口,尤其在React工程中是很常用的,如下:

export default class Carousel extends React.Component<Props,State>{}

由于组件需要传入props的类型Props,同时有需要设置默认props即defaultProps,这时候更加适合使用class作为接口
先声明一个类,这个类包含组件props所需的类型和初始值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端小超人rui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值