TypeScrip类

110 阅读4分钟

类的基本定义与使用

// 声明一个 Greeter 类
// 这个类有 3 个成员:一个叫做 message 的属性,一个构造函数和一个 say 和 getName 方法
class Greeter {
   // 声明属性 
   message: string,
   
   // 定义构造函数:为了将来实例化对象的时候,可以直接对属性的值进行初始化
   constructor(message: string="可定义初始化值"){
       this.message = message
   }
   
   // 一般方法
   say(): string {
      return "hello" +  this.message
   },
   getName(str: string): string {
      console.log(`我是${this.message},`, str)
   }
}


// 使用 new 构造了 Greeter 类的一个实例
const greeter = new Greeter("栗子")
// 调用实例方法
greeter.say()
greeter.getName("开心的一天")

类与类的继承

  • A类继承了B类,此时A类叫子类(派生类),B类叫基类(超类/父类)
  • 类和类之间如果要有继承关系,需要使用extends关键字
  • 子类中可以调用父类的构造函数,使用的是super关键字(包括调用父类中的实例方法,也可以使用super)
  • 子类中可以重写父类的方法
// 定义一个类,作为基类(超类/父类)
class Animal {
    name: string,
    constructor(name: string){
        this.name = name
    }
    run(distance: number = 0){
        console.log(`${this.name}跑了${distance}米`)
    }
}

// 定义一个类,继承自Animal
class Dog extends Animal {
   constructor(name: string){
       // 调用父类的构造方法,使用super
       super(name)
   } 
   // 重新父类的方法
   run(distance: number = 0){
        console.log("重写了父类的方法")
        console.log(`${this.name}跑了${distance}米`)
        // 调用父类型的一般方法
        super.run(distance)
   }
}

const animal = new Animal("动物集合")
animal.run(100)

多态

父类型的引用指向了子类型的对象,不同类型的对象针对相同的方法,产生了不同的行为

修饰符

  • 修饰符(类中成员的修饰符):主要是描述类中的成员(属性,构造函数,方法)的可访问性
  • 访问修饰符: 用来描述类内部的属性/方法的可访问性
  • 公共(public) 默认值,公开的外部也可以访问
  • 私有(private) 只能在类内部可以访问
  • 受保护(protected) 类内部和子类可以访问

readonly修饰符

  • 是一个关键字,对类中的属性成员进行修饰,修饰后,该属性成员,就不能在外部被随意的修改了
  • 构造函数中,可以对只读的属性成员数据进行修改
  • 如果构造函数中没有任何的参数,类中的属性成员此时已经使用readonly进行修饰了,那么外部也是不能对这个属性值进行更改的
  • 构造函数中的参数可以使用readonly进行修饰,一旦修饰了,那么该类中就有了这个只读的成员属性了,外部可以访问,但是不能修改
  • 构造函数中的参数可以使用public及privte和protected进行修饰,无论是哪个进行修饰,该类中都会自动的添加这么一个属性成员
// 定义一个类
class Person {
    // 属性
    // readonly name: string='小栗子' // 初始值
    readonly name: string
    constructor(name: string = "大栗子"){
        this.name = name
    }
    sayHi(){
        // 类中的普通方法中,也是不能修改readonly修饰的成员属性值
        // this.name = "大栗子"
    }
    
}

存取器

让我们可以有效的控制对对象中成员的访问,通过getters和setters来进行操作

// 外部可以传入姓氏和名字数据,同时使用set和get控制姓名的数据,外部也可以进行修改操作
class Person {
   firstName: string
   lastName: string   
   constructor(firstName: string, lastName: string){
      this.firstName = firstName
      this.lastName = lastName
   }
   // 读取器----负责读取数据的
   get fullName() {
       return this.firstName + '_' + this.lastName
   }
   // 设置器----负责设置数据的(修改)
   set fullName(val) {
       let names = val.split('_')
       this.firstName = names[0]
       this.lastName = names[1]
   }
}

// 实例化对象
const person: Person = new Person('上官', '栗子')
// 获取该属性成员属性
console.log(person.fullName)
// 设置该属性的数据
person.fullName = '诸葛_孔明'

静态属性

  • 在类中通过static修饰的属性或者方法,就是静态的属性及静态的方法,也称之为:静态成员
  • 静态属性在使用的时候是通过类名.的这种语法来调用的
// 定义一个类
class Person {
   name1: string = '实例属性'
   // 静态属性
   static name2: string = '小栗子'
   // 构造函数是不能通过static来进行修饰的
   // 静态方法
   static sayHi() {
      console.log("2222")
   }
}

// 通过类名.静态属性的方式来访问该成员数据
console.log(Person.name2)
// 通过实例对象调用的属性(实例属性)
console.log(new Person().name1)

抽象类

  • 包含抽象方法(抽象方法一般没有任何的具体内容的实现),也可以包含实例方法
  • 抽象类是不能被实例化,为了让子类进行实例化及实现内部的抽象方法
  • 抽象类的目的或作用最终都是为子类服务的
  • 抽象类可以包含成员的实现细节
  • abstract 关键字是用于定义抽象类和在抽象类内部定义抽象方法
// 定义一个抽象类
abstract class Person {
    // 抽象属性
    abstract name: string
    // 抽象方法不能有具体的实现
    abstract eat(): any
    // 实例方法
    sayHi() {
       console.log('您好啊!!!')
    }
}

// 定义一个子类(派生类)
class Chart extends Person {
    name: string = "栗子"
    // 重新的实现抽象类中的方法,此时这个方法就是当前Chart类的实例方法了
    eat() {
      console.log("吃吃吃")
    }
}

// 实例化Chart的对象
const chart: Chart = new Chart()
chart.eat()
// 调用的是抽象类中的实例方法
chart.sayHi()