TypeScript 类 (class) 详解

在js中定义一个类之后,是动态加入属性的(在构造函数中动态添加),但是在TS中是不允许这样的,TS固定必须在定义对象的时候就确定对象中所拥有的属性。TS中认为属性是不可以随意增删的。

使用属性列表描述类中的属性

class User {
  // 属性列表
  id: number
  name: string
  age: number
  gender: "男" | "女" = "男"
}

类的属性可以在顶层声明,也可以在构造方法内部声明。对于顶层声明的属性,可以在声明同时发给出类型约束。如果不给出类型,TypeScript会认为该属性是any类型。如果声明时给出初始值,可以不写类型,TS会自行推断属性的类型。

属性的初始化检查

在tsconfig中配置:strictPropertyInitialization为true,就会检查属性是否设置了初始值,如果没有就报错。如果打开了这个配置,但是某些情况下,不是声明时赋值或在构造方法中赋值,为了防止这个配置报错,可以使用非空断言:

在属性名后面加一个“!”

class User {
  // 属性列表
  id!: number
  name!: string
  age!: number
  gender: "男" | "女" = "男"
}

readonly修饰符

在类中属性名前面加上 readonly 修饰之后,表示该属性是只读的,实例对象不能修改这个属性。readonly修饰可以写在顶层,也可以写到构造方法中。

class User {
  // 属性列表
  readonly id: number
  name: string
  age: number
  gender: "男" | "女" = "男"
  constructor() {
    this.id = 123
  }
}

 上面例子中,构造方法内部设置只读属性的初始值,这是可以的。如果在顶层和构造方法中同时设置了初始值,那么最终会以构造方法中设置的值为准,但是在其他方法中修改只读属性都会报错。

属性存取器

存取器是特殊的类方法,包括获取方法(getter)、赋值方法(setter)两种方法。他们用于读写某个属性。

class User {
  // 属性列表
  readonly id: number
  _name: string
  age: number

  get name() {
    return this._name
  }

  set name(val: string) {
    this._name = val
  }
}
 存取器的规则:
  1. 如果某个属性只有get方法,没有set方法,那么该属性自动成为只读属性。
  2. set方法的参数类型,必须兼容get方法的返回值类型,否则报错。
  3. get方法与set方法的可访问性必须一直,要么都为公开方法,要么都为私有方法。

访问修饰符

访问修饰符可以控制类中的某个成员的访问权限。

public 公开的

public修饰符表示此属性是公开成员,外部可以自由访问。public是默认修饰符,通常情况下为了代码的可读性,public是省略不写的。

private 私有的

private修饰符表示私有成员,只能用在当前类的内部,类的实例和子类都不能使用该成员。

class Test {
  private x: number = 0 
}
const t = new Test()
t.x // 报错 属性“x”为私有属性,只能在类“Test”中访问。
严格的说,private定义的私有成员,并不是真正意义上的私有成员,因为编译为JavaScript后,private关键字会消失,这是外部访问该成员就不会报错。但是ES6引入了自己的私有成员写法#propName,因此建议不使用private,改用ES6的写法,获得真正意义的私有成员。                                                                       
                                                                                                          ----------阮一峰教程
protected 受保护的

protected 修饰符表示该成员是受保护的成员,只能在类的内部使用该成员,实例对象无法使用该成员,但是在子类的内部可以使用。

类的继承

继承的概念

继承可以描述类与类之间的关系,可以将公共的部分抽离出来,提高代码的复用性。

如果A和B都是类,并且可以描述为A是B,则A和B形成继承关系;

- B是父类,A是子类;

- B派生出A,A继承自B;

- B是A的基类,A是B的派生类;

class Tank {
  x: number = 0
  y: number = 0
}

class PlayerTank extends Tank{
  // 子类的重写
  // 子类覆盖父类的属性活成员 无论是属性活方法,都可以对父类进行重写(属性类型不可更改)
  x: number = 20
  y: number = 20
}

class EnemyTank extends Tank{}

// boss坦克既继承了地方坦克的属性和方法,也继承了Tank类的属性和方法。
class BossTank extends EnemyTank{}

继承的单根行和传递性

单根行:一个类只能继承一个父类;

传递性:例如上个例子,BossTank继承了EnemyTank,但是EnemyTank继承了Tank,可以说Tank也是BossTank的父类。

抽象类

什么是抽象类?

有时某个类只表示一个抽象概念,主要用于提取子类的公有成员,而不能直接创建它的实例对象,则该类称为抽象类。

创建抽象类

在class关键字前用abstract修饰,表示该类不能被实例化。只能当做其他类的模板。

abstract class Chess {} // 用abstract修饰,表示该类为抽象类,该类不可以创建对象
class Horse extends Chess {}
class Gun extends Chess { }
class Soldier extends Chess { }
const horse = new Horse()
const chess = new Chess() // 报错

例如中国象棋中:每一个棋子都有相同的属性和方法,但是每一个棋子都有自己的特性,所以我们需要定义一个棋子的类,但是我们不会单独使用这个类,这个棋子类就是抽象类。

抽象成员

  • 在父类中可能知道有些成员是必须存在的,但是不知道该成员的具体实现或值是什么,所以需要一种强约束让继承该类的子类必须要实现该成员。
  • 抽象类中可以有抽象成员,抽象成员是没有具体实现的成员,这些抽象成员只能在抽象类中,抽象成员只能在子类中实现。
// 抽象属性
abstract class Chess {
  x: number = 0
  y: number = 0
  abstract readonly name: string; // 抽象属性
  abstract isMove(); // 抽象方法
}

class Horse extends Chess {
  readonly name: string = "马"
  isMove(){
    // ...
  }
}

class Gun extends Chess {
  readonly name: string
  constructor() {
    super()
    this.name = "炮"
  }
  isMove(){
    // ...
  }
}

class Soldier extends Chess {
  get name() {
    return "兵"
  }
  isMove(){
    // ...
  }
}

静态成员

静态成员是指:不需要创建实例对象,直接通过类访问的成员。属于某个构造函数的成员,而不属于某个对象的成员。

使用static修饰的成员称之为静态成员。

例如:isNaN是只能通过Number访问的成员,因为他是属于Number的构造函数成员,而不是属于某个对象的成员。

class User {
  userName: string
  password: string
  static login(userName: string, password: string): User|undefined {
    // todo
  }
}
// 用户登录的时候不需要创建一个用户对象,直接通过类名调用login方法即可
const user = User.login("tom", "123")
静态方法中的this

实例方法中的this指向是调用该方法的对象,而静态方法中的this是调用该方法的类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值