【TypeScript】类

266 阅读5分钟

这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战


TypeScript——类

(1)概念

  • 类是一种面向对象计算机编程语言的构造,是创建对象的蓝图,描述了所创建的对象共同的属性和方法

(2)定义

这里的类与ES6中的类大致类似,所以与之前相同的部分,这里仅作简单介绍

  • 使用class关键字来定义一个类,然后使用new来创建一个基于类的对象

    • 使用new创建实例时,会执行构造函数并初始化
    • 通过添加static关键字来定义一个静态属性/方法
    class Person {
        // 静态属性
        name: string = "Ruovan"
        // 成员属性
        age: number
    
        // 构造函数 - 执行初始化操作
        constructor(name: string) {
            this.name = name
        }
    
        // 静态方法
        static getUserName() {
            return "My name is Ruovan."
        }
    
        // 成员方法
        say() {
            return "Hello, My name is " + this.name
        }
    }
    
    // 使用 new 创建一个基于 Gretter 类型的对象
    let person = new Person("Ruovan")
    
    

(3)继承

  • 继承

    • 指的是一个类(子类、子接口)可以继承自另一个类(父类、父接口),以扩展现有的类
    • 通过extends关键字来实现继承
    • 继承可以从被继承的类中继承属性和方法,这个被继承的类称为基类或者父类
    // 基类 -- 父类 -- 超类
    class Father {
        name = 'Father'
        getFatherName(){
            return this.name;
        }
    }
    // 派生类 -- 子类
    class Son extends Father {
        getSonName(){
            return 'Son'
        }
    }
    // 实例
    const son = new Son()
    
    // 实例里面 既有子类自身的方法 getSonName, 又有父类的方法 getFatherName
    console.log(son.getFatherName()); // Father
    console.log(son.getSonName()) // Son
    
    

(4)重写

  • 重写

    • 在子类继承父类方法之后,还可以在子类里面去重写父类的方法,以覆盖父类的方法
    • 但同时,在重写之后,又可以使用super关键字去重新调用父类的方法
    class Father {
        name = 'Father'
        getFatherName(){
            return this.name
        }
    }
    class Son extends Father {
        getSonName() {
            return 'Son'
        }
        getFatherName() {
            return 'Son Father'
        }
    }
    // 实例
    const son = new Son()
    // 这个时候子类的 getFatherName 会把父类的 getFatherName 给覆盖了
    console.log(son.getFatherName()) // Son Father
    
    // 如果 Son 写成如下
    class Son extends Father {
        getSonName() {
            return 'Son'
        }
        getFatherName() {
            // super.getName() 
            // 使用 super.getName()  可以调用父类的方法    
            return 'new Son' + super.getFatherName() // new Son Father 
        }
    }
    
    

(5)修饰符

  • 私有类型

    • 使用private来定义一个私有的属性/方法
  • 私有类型只允许在类内部使用

    class Father {
        private name = 'Father'
        getFatherName(){
            console.log(this.name) // 在当前类的内部,可以被调用    
        }
    }
    const father = new Father()
    console.log(father.name) // 但是在类外无法访问这个属性,会报错
    
    
  • 保护类型

    • 使用protected来定义一个被保护的属性/方法
    • 保护类型只允许在类内部继承的子类中使用
    class Father {
        protected name = 'Father'
        getFatherName(){
            console.log(this.name) // 在当前类的内部,可以被调用
        }
    }
    class Son extends Father {
        getSonName() {
            console.log(this.name) // 继承了父类的name 允许被调用    
        }
    }
    
    
  • 公共类型

    • 使用public来定义一个公共的属性/方法
    • 默认的所有属性/方法前面都是public,因此可以不写,且,公共类型允许在类外部使用
    class Father {    
        // 默认 public    
        name = 'Ruovan'
        // public name = 'Ruovan'
        getFatherName(){        
            console.log(this.name)    
        }
    }
    const father = new Father()
    console.log(father.name)
    
    
  • 只读类型:使用readonly来定义一个只读的属性

    • 只读属性必须在声明时或构造函数里被初始化
    • 只读属性初始化后,无法再更改
    class Father {    
        readonly name: string = 'Ruovan'    
        constructor(name: string) {        
            this.name = name    
        }
    }
    let father = new Father('Ruovan')
    father.name = 'composition' // error
    
    

(6)构造函数

  • 在使用new创建一个实例的时候,构造函数constructor()会马上执行

    class Person {    
        let name: string    
        constructor(name: string) {        
            this.name = name    
        }
    }
    const person = new Person('Ruovan')
    
    
  • 参数属性:

    • 参数属性可以方便地让我们在一个地方定义并初始化一个成员
    • 仅在构造函数里使用 readonly name: string 参数来创建和初始化 name 成员
      • 即,把声明和赋值合并,简化代码
    class Person {    
        constructor(readonly name: string) {    
            this.name = name
        }
    }
    const person = new Person('Ruovan')
    console.log(person.name)
    
    
  • 继承时:

    • 如果父类有构造器,子类也有构造器,那么子类必须调用父类构造函数,且必须按照父类构造器的要求传参
    class Father{
        constructor(public name:string){
    
        }
    }
    class Son extends Father{
        constructor(public age:number){
            super('Ruovan')
        }
    }
    const son = new Son(24)
    console.log(son.age) // 24
    console.log(son.name) // Ruovan
    
    

(7)存取器

  • 存取七:即既可以读取这个属性,又可以更改这个属性

    • 通过 getters/setters 来截取对对象成员的访问
      • 在这个方法中对变量进行加工处理之后,再暴露出去
    • 同时,外界可以直接调用get/set的方法,去读取或者更改这个属性
    class Person {
        firstName: string = 'A'
        lastName: string = 'B'
        get fullName () {
            return this.firstName + '-' + this.lastName
        }
        set fullName (value) {
            const names = value.split('-')
            this.firstName = names[0]
            this.lastName = names[1]
        }
    }
    
    const person = new Person()
    console.log(person.fullName) // A-B
    
    person.firstName = 'C'
    person.lastName =  'D'
    console.log(person.fullName) // C-D
    
    person.fullName = 'E-F'
    console.log(person.firstName, person.lastName) // E F
    
    

(8)单例模式

  • 单例模式是指:永远只会生成一个实例

    • 通过instance关键字来判断
    class Demo{
        private static instance:Demo 
        // 不允许被调用 规避创建实例的情况
        private constructor(public name:string){
            
        }
        static getInstance(){
            if(!this.instance){ //如果没有创建  创建让instance储存
                this.instance = new Demo('demo')
            }
            return this.instance
        }
    
    }
    const demo = Demo.getInstance()
    
    

(9)抽象类

  • 抽象类:即,将具有相同属性的部分做一个封装,然后具体的内容由子类去定义

    • 通过abstract关键字定义一个抽象类
    • 需要注意的是:
      • 抽象类只能被继承,不能用这个类去创建实例
      • 子类在继承了父类的抽象类之后,必须在子类里面去实现父类的抽象方法,即具体实现由子类完成
    // abstract 去定义一个抽象类
    abstract class Person{
        getClass(){
            return 'Person'
        }
        // 抽象方法,只有一个方法,没有具体的实现
        abstract getSex(): string
    }
    class Woman extends Person {
        // 在子类中来实现具体的 抽象类 的方法    
        getSex(){
            return 'female'
        }
    }
    class Man extends Person {
        getSex(){
            return 'male'
        }
    }
    
    

本人前端小菜鸡,如有不对请谅解