类的基本定义与使用
// 声明一个 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()