今天我们来聊聊类类型

什么是类

  :描述了所创建的对象共同的属性和方法。
  :可以理解为模版,通过模板可以实例化对象,体现的是面向对象的编程思想。
  类的目的:实例化对象,实现面向对象的编程思想

TypeScript中类的定义及使用

  TypeScript 是面向对象的 JavaScript。
  TypeScript 支持面向对象的所有特性,比如 类、接口等。
  TypeScript 类定义方式如下:

1、声明/定义一个类
class class_name { 
	// 类作用域
	//a、定义属性
	//b、定义构造函数:为了将来实例化对象的时候,可以对属性的值进行初始化
	//c、定义实例方法
}
2、实例化对象
const xx = new class_name()

  再来举个案例吧

//1、定义/声明一个类
class Person {
  //a、定义属性
  name:string
  age:number
  sex:string
  //b、定义构造函数:为了将来实例化对象的时候,可以对属性的值进行初始化
 constructor(name:string="Amy",age:number=18,sex:string){//此写法是为了表示构造函数可以传递初始值
    //更新对象中的属性数据
    this.name = name//访问的是类的成员
    this.age = age
    this.sex = sex
  }
  //c、定义实例方法
  say(str:string):string{
    console.log(`你好,我是${this.name},我今年${this.age}了,我是${this.sex}孩子,`,str)
  }
}
//2、实例化对象
const person = new Person("jack",55,"男")
person.say("你叫什么呢?")

  是不是对于类的记忆又回来了呢?
  TypeScript的类是基于JavaScript的类的面向对象的方式特性,并且编译后的 JavaScript 可以在所有主流浏览器和平台上运行,

TypeScript类的继承性

  TypeScript 支持继承类,即我们可以在创建类的时候继承一个已存在的类,这个已存在的类称为父类,继承它的类称为子类。
  类继承使用关键字 extends,子类可以使用父类的构造函数(通过super(传递参数)实现)和父类的实例方法(使用super.say()实现),子类可以重写父类的方法

//继承:类与类之间的关系及继承后类与类之间的叫法,一旦发生了继承关系,就出现了父子类的关系
//a类继承了b类,那么a类叫子类,b叫基类
//子类:派生类
//基类:超类(父类)

//1、定义一个类,作为一个基类
class Person {
  //a、定义属性
  name:string
  age:number
  sex:string
  //b、定义构造函数:为了将来实例化对象的时候,可以对属性的值进行初始化
constructor(name:string="Amy",age:number=18,sex:string){
    //更新对象中的属性数据
    this.name = name//访问的是类的成员
    this.age = age
    this.sex = sex
  }
  //c、定义实例方法
  say(str:string):string{
    console.log(`你好,我是${this.name},我今年${this.age}了,我是${this.sex}孩子,`,str)
  }
}
//1.1、定义一个子类,继承自Person
class Student extends Person{
   constructor(name:string,age:number,sex:string){
    super(name,age,sex)//使用super调用父级构造函数
  }
  //可以调用父级的方法
  say(){
    console.log(“我是学生中的say方法”)
    super.say("你是谁呢")//子类调用父类的实例方法用super关键字
  }
}
//2、实例化父类实例对象
const person = new Person(“白菜”,18,“女”)
person.say("啦啦")
//2.1、实例化子类实例对象
const student  = new Student(“萝卜”,88,“男”)
student.say()

TypeScript中类的多态

  多态:父类型的引用指向了子类型的对象,不同类型的对象针对相同的方法,产生了不同的行为。
  如果你足够熟悉javascript的话,对于多态可以只用了解上面的内容,如果有不太了解的地方,我们就用下面这个实例一起来看看吧

//多态:父类型的引用指向了子类型的对象,不同类型的对象针对相同的方法,产生了不同的行为
//1:定义一个父类:动物
class Animal {
  //a、定义一个属性
  name:string
  //b、定义一个构造函数
  constructor (name:string="动物"){
    this.name = name
  }
  //定义一个实例方法
  run(dis:number = 0){
    console.log(`我是${name},我跑了${dis}米`,)
  }
}
//1.1:狗,继承了父类
class Dog extends Animal{
  constructor (name:string="小狗"){
    //调用父类的构造函数,实现子类中的属性的操作
    super(name)
  }
  //实例方法:重写父类中的实例方法
 	run(dis:number = 10){
    console.log(`我是${name},我跑了${dis}米`,)
  }
}
//1.1:定义第二个子类:猪,继承了父类
class Pig extends Animal{
  constructor (name:string="小猪"){
    //调用父类的构造函数,实现子类中的属性的操作
    super(name)
  }
  //实例方法:重写父类中的实例方法
 	run(dis:number = 200){
    console.log(`我是${this.name},我跑了${dis}米`,)
  }
}

//2、实例化父类对象
const Ani :Animal = new Animal("动物")
Ani.run()
//2.1:实例化子类dog对象
const dog :Dog= new Dog("小黄")
dog.run()
//2.2:实例化子类pig对象
const pig:Pig= new Pig("八戒")
pig.run()

//3.1父类和子类的关系:父子关系,此时,父类类型创建了子类的对象
const dog1:Animal= new Dog("发财")
//不同类型的对象针对相同的方法,产生了不同的行为
dog1.run()
const pig1:Animal= new Pig("猪咪")
pig1.run()

//3.1不同类型的对象针对相同的方法,产生了不同的行为
function showrun (Ani:Animal){
  Ani.run()
}
showrun(dog1)
showrun(pig1)

TypeScript中类的修饰符

  修饰符:类中成员的修饰符描述类中的成员(属性、构造函数、方法)的可访问性

  • 公共:public,类中成员默认的修饰符,代表任何位置都可访问类中的成员
  • 私有:private,类中成员的私有修饰符,类中的成员使用private,外部成员无法访问成员数据。同时子类中也是无法访问该成员数据的
  • 受保护的:protected,类中的成员受保护修饰符,类中成员使用protected修饰时,外部无法访问这个成员数据,但是子类是可以访问这个成员数据的。
//1、定义一个类
class Person {
  //a、定义一个属性
  //public name:string  //public修饰了这个name属性,此时任何位置都可访问类中的成员
  private name:string //private修饰了这个属性,此时console.log(per.name)的外部访问会报错;此时子类student的super方法也会报错
  //b、定义一个构造函数
  constructor (name:string="动物"){
    this.name = name
  }
  //定义一个实例方法
  run(dis:number = 0){
    console.log(`我是${this.name},我跑了${dis}米`,)
  }
}
//1.1:狗,继承了父类
class student extends Person{
  constructor (name:string){
    //调用父类的构造函数,实现子类中的属性的操作
    super(name)
  }
  //实例方法:重写父类中的实例方法
 	play(){
    console.log()
  }
}
//2、实例化对象
const per = new Person(“猪猪精”)
//类的外面可以访问类的属性成员
console.log(per.name)
per.run()

TypeScript中类的readonly修饰符

  readonly修饰符:只读的,是一个关键字,对类中的属性成员进行修饰,修饰后,该属性成员就不能在外部被随意修改了

1、readonly修饰类中的成员属性

  让我们先来看一个案例,在对ts的readonly修饰符进行总结吧

//1、定义一个类
class Person {
	//属性
 readonly name:string
  //构造函数
  constructor(name:string){
    //更新对象中的属性数据
    this.name= name  //不报错
  }
  say(){
    console.log(`我是${this.name}`)
    this.name = "黑柴" **报错:**类中的普通方法中,也是不能够对readonly修饰符修饰的成员属性值进行修改
  }
}

//2、实例化一个对象
const person:Person = new Person("欻欻")
console.log(person)
console.log(person.name)//欻欻

person.name = "黑柴"  **报错**:添加readonly修饰符后报错:此时person的name属性是只读的,不能被其外部修改
//console.log(person.name)//黑柴

  此时我们可以发现:

  • 类的构造函数中,可以对只读属性成员的属性值进行修改:即 更新对象中的属性数据后this.name= name 不报错
  • 类的构造函数中,如果没有任何参数,类中的属性成员已经使用readonly修饰,外部的成员也是不能够对这个属性值进行更改的
  • 类中的普通方法中,也是不能够对readonly修饰符修饰的成员属性值进行修改 ,say(){this.name = "黑柴" //报错:类中的普通方法中,也是不能够对readonly修饰符修饰的成员属性值进行修改 }
  • 实例化对象后,外部不能够对readonly修饰符修饰的类的属性值进行修改 person.name = "黑柴" //添加readonly修饰符后报错:此时person的name属性是只读的,不能被其外部修改

2、readonly修饰类中构造函数的参数

  我们再来看看readonly修饰类中构造函数的参数有什么样的特点吧

//1、定义一个类
class Person {
  //构造函数
  constructor(readonly name:string){
    this.name= name  //不报错且可以注释掉
  }
}
//2、实例化一个对象
const person:Person = new Person("欻欻")
console.log(person)
console.log(person.name)//欻欻
person.name = "黑柴" //报错,外部无法修改类中的name属性成员值的
  • //构造函数中的name参数:一旦使用readonly修饰符修饰,那么name参数可以叫做参数属性 constructor(readonly name:string){}
  • 构造函数中的name参数,一旦使用readonly修饰符修饰,那么Person中就有了一个name的属性成员
  • 构造函数中的name参数,一旦使用readonly修饰符修饰,外部无法修改类中的name属性成员值的
  • 构造函数中的name参数,一旦使用rpublic修饰符修饰,Person中就有了一个公共的name的属性成员

TypeScript中类的存取器

  TypeScript支持通过getters/setters来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。
  首先,我们从一个简单使用存取器的例子开始

  • set :设置器:负责设置及修改数据
  • get :读取器:负责读取数据,必须要有返回值
//需求:外部传入形式和名字数据,同时通过set/get控制姓名的数据,外部也可以进行修改和操作
//1、定义一个类
class Person {
  //姓名的成员属性(外部可以访问也可以进行修改)
  firstName:string
  lastName:string
  //构造器
  constructor(firstName:string,lastName:string){
    this.lastName = lastName
    this.firstName = firstName
  }
  //set :设置器:负责设置及修改数据
  set fullName(val){
    let name = val.split("-")
    this.firstName= name[0]
    this.lastName= name [1]
  }
  //get :读取器:负责读取数据,必须要有返回值
  get fullName(){
    return this.firstName+"-"this.lastName
  }
}
//2、实例化对象
const person = new Person("东方","不败")
console.log(person)
console.log(person.fullName)//可以获取到,称为获取该属性成员属性
person.fullName("诸葛-四郎")//可以进行设置,称为存取该属性成员数据
console.log(person.fullName)

TypeScript中类的静态成员

  静态成员:在类中通过static修饰符修饰的属性或方法,称为类的静态属性及静态方法,也称之为静态成员。构造函数是不能通过static进行修饰
  静态成员在使用的时候,是通过类名.静态方法()的方式调用的

  • 静态属性
  • 静态方法
      还是通过案例来查看
//1、定义一个类
class Person {
  //静态属性
 static name1:string
  constructor( name1:string){
    //this.name1= name1  //此时,this是实例对象,name1是静态属性,不能通过实例对象直接调用静态属性来使用
    
  }
 static say(){
    console.log("你好")
  }
}
//2、实例化一个对象
const person:Person = new Person("欻欻")
//通过实例对象调用的属性(实例属性)
//console.log(person.name1)//报错:此时,this是实例对象,name1是静态属性,不能通过实例对象直接调用静态属性来使用
//通过实例对象调用的方法(实例方法)
//person.say()
Person.say()  //通过类.静态方法名的方式来调用类的静态方法

Person.name1 = "xinxin" //通过类名.静态属性的方法来访问类中成员的属性
  • 使用 静态属性后,不能在构造函数中使用this来更改对象中的属性数据,因为this是实例对象,name1是静态属性,不能通过实例对象直接调用静态属性来使用
  • 使用 静态方法后,不能通过实例方法来调用静态方法,而是需要使用类.静态方法名的方式来调用类的静态方法