文章目录
- 面向对象—类
- 类的作用
- 类的定义
- 类的继承
- 类的成员修饰符
- 类的类型
- 抽象类abstract
- 对象类型的属性修饰符
- 索引签名
- 枚举类型
面向对象—类
类的作用
TypeScript作为JavaScript的超集,也是支持使用class关键字的,并且还可以对类的属性和方法等进行静态类型检测。
-
在封装某些业务的时候,类具有更强大封装性。
-
类的定义我们通常会使用class关键字:
-
在面向对象的世界里,任何事物都可以使用类的结构来描述;
-
类中包含特有的属性和方法;
-
类的定义
- 使用class关键字来定义一个类;
- 声明类的属性:在类的内部声明类的属性以及对应的类型
- 如果类型没有声明,那么它们默认是any的;
- 我们也可以给属性设置初始化值;
- 在默认的strictPropertyInitialization模式下面我们的属性是必须 初始化的,如果没有初始化,那么编译时就会报错;如果我们在strictPropertyInitialization模式下确实不希望给属性初始化,可以使用 name!: string语法;
- 类可以有自己的构造函数constructor,当我们通过new关键字创建 一个实例时,构造函数会被调用;构造函数不需要返回任何值,默认返回当前创建出来的实例;
- 类中可以有自己的函数,定义的函数称之为方法;
class Person {
//声明类的属性
name!: string
age: number
//构造函数
constructor(name: string, age: number){
//设置初始化值
//name可以不初始化,因为声明时name!: string
//this.name = name
this.age = age
}
//类中自己的函数
running() {
console.log("Person:"this.name + "running!")
}
eating() {
console.log("Person:"this.name + "eating!")
}
}
类的继承
- 面向对象的其中一大特性就是继承,继承不仅仅可以减少我们的代码量,也是多态的使用前提。
- 使用extends关键字来实现继承,子类中使用super来访问父类。
- 例如:Student类继承自Persoon类:
- Student类可以有自己的属性和方法,并且会继承Person的属性和方法;
- 在构造函数中,我们可以通过super来调用父类的构造方法,对父类中的属性进行初始化;
class Student extends Person {
//Student类的属性声明
sno: number
constructor(name: string, age: number, sno: number){
super(name, age)
this.sno = sno
}
//Student类的方法stdying
studying() {
console.log("Student:"this.name + "studying")
}
eating() {
console.log("Student:" + "student eating!")
}
running() {
super.running();
console.log("Student:" + "student running!")
}
}
const s = new Student("kobe", 19, 188888)
s.studying()
s.eating()
s.running()
console.log(s.age)
console.log(s.name)
console.log(s.sno)
//输出结果:
Student:kobestudying
Student:student eating!
Person:koberunning!
Student:student running!
kobe
19
188888
类的成员修饰符
在TypeScript中,类的属性和方法支持三种修饰符: public、private、protected:
- public 修饰的是在任何地方可见、公有的属性或方法,默认编写的属性就是public的;
- private修饰的是仅在同一类中可见、私有的属性或方法;
- protected 修饰的是仅在类自身及子类中可见、受保护的属性或方法;
- 只读属性readonly
如果有一个属性我们不希望外界可以任意的修改,只希望确定值后直接使用,那么可以使用readonly:
- getters/setters
在前面一些私有属性我们是不能直接访问的,或者某些属性我们想要监听它的获取(getter)和设置(setter)的过程,这个时候我们可以使用存取器。
class Person {
private _name: string
//setters属性
set name(newValue) {
this._name = newValue
}
//getters属性
get name() {
return this._name
}
constructor(name: string) {
this.name = name
}
}
const p = new Person("jack")
p.name = "kobe" //调用setters函数
console.log(p.name) //调用getters函数
- 参数属性
TypeScript 提供了特殊的语法,可以把一个构造函数参数转成一个同名同值的类属性。这些就被称为参数属性。
- 你可以通过在构造函数参数前添加一个可见性修饰符 public private protected 或者 readonly 来创建参数属性,最后这些类 属性字段也会得到这些修饰符;
类的类型
类本身也是可以作为一种数据类型的:
抽象类abstract
在TypeScript中没有具体实现的方法(没有方法体),就是抽象方法。
抽象方法,必须存在于抽象类中;
抽象类是使用abstract声明的类;
-
举个栗子理解一下:我们知道,继承是多态使用的前提。所以在定义很多通用的调用接口时, 我们通常会让调用者传入父类,通过多态来实现更加灵活的调用方式。但是,父类本身可能并不需要对某些方法进行具体的实现,所以父类中定义的方法,我们可以定义为抽象方法。
-
抽象类特点:
- 抽象类是不能被实例化(也就是不能通过new创建)
- 抽象类可以包含抽象方法,也可以包含有实现体的方法;
- 有抽象方法的类,必须是一个抽象类;
- 抽象方法必须被子类实现,否则该类必须是一个抽象类;
对象类型的属性修饰符
对象类型中的每个属性可以说明它的类型、属性是否可选、属性是否只读等信息。
-
可选属性
- 我们可以在属性名后面加一个 ? 标记表示这个属性是可选的;
-
只读属性
-
在 TypeScript 中,属性可以被标记为 readonly,这不会改变任何运行时的行为;
-
但在类型检查的时候,一个标记为 readonly的属性是不能被写入的。
-
索引签名
有的时候,我们不能提前知道一个类型里的所有属性的名字,但是我们知道这些值的特征。这种情况,我们就可以用一个索引签名来描述可能的值的类型。
- 一个索引签名的属性类型必须是 string 或者是 number。虽然 TypeScript 可以同时支持 string 和 number 类型,但数字索引的返回类型一定要是字符索引返回类型的子类型;
枚举类型
- 基本使用
//定义枚举类型
enum Direction {
LEFT,
RIGHT
}
function turnDirection(direction: Direction) {
switch(direction) {
case Direction.LEFT:
console.log("左移")
break
case Direction.RIGHT:
console.log("右移")
break
}
}
//监听键盘的点击
turnDirection(Direction.LEFT)
- 枚举类型的值
- 枚举类型默认是有值的,比如上面的枚举,默认值是这样的:
enum Direction {
LEFT = 0,
RIGHT = 1
}
- 可以给枚举类型赋值
enum Direction {
//若给LEFT赋值为100
LEFT = 100,
//那么RIGHT默认会从100递增为101
RIGHT = 101
}
- 可以给枚举类型赋其他类型的值
enum Direction {
LEFT = "LEFT",
RIGHT = "RIGHT"
}