Skip to content
此页目录
本文总阅读量

TypeScript 类

ts 中 class 与 ES6 使用方式一致

修饰符

  • public:默认值,公开的外部也可以访问
  • protected:类内部和子类可以访问,类外部没法访问
  • private:只能类内部访问 子类和外部没法访问
  • readonly:只读的属性,必须在声明和构造函数中初始化,可以和前面关键字搭配使用

public

默认值,公有属性

ts
class Person {
  public name: string; /* 公有属性 */
  constructor(name: string){
    this.name = name;
  }
  getName():string{ /* 默认 public 公有属性 */
    return this.name;
  }
}
console.log(new Person('tom').name); // tom
console.log(new Person('tom').getName()); // tom

class Son extends Person{
  constructor(name:string){
    super(name)
  }
  getName(): string {
    return `这是子类:${this.name}`
  }
}

console.log(new Son('son').name); // son
console.log(new Son('son').getName()); // 这是子类:son

protected

类内部和子类可以访问,类外部没法访问

ts
class Person {
  protected name: string;
  constructor(name: string){
    this.name = name;
  }
  getName():string{
    return this.name;
  }
}
console.log(new Person('tom').name); // 编译器报错:属性“name”受保护,只能在类“Person”及其子类中访问。
console.log(new Person('tom').getName()); // tom

class Son extends Person{
  constructor(name:string){
    super(name)
  }
}

console.log(new Son('son').name); // 编译器报错:属性“name”受保护,只能在类“Person”及其子类中访问。
console.log(new Son('son').getName()); // son

private

只能类内部访问

ts
class Person {
  private name: string;
  constructor(name: string){
    this.name = name;
  }
  getName():string{
    return this.name;
  }
}
console.log(new Person('tom').name); // 编译器报错:属性“name”受保护,只能在类“Person”及其子类中访问。
console.log(new Person('tom').getName()); // tom

class Son extends Person{
  constructor(name:string){
    super(name)
  }
  getName():string{
    return this.name; // 报错:属性“name”为私有属性,只能在类“Person”中访问。
  }
}

console.log(new Son('son').name); // 编译器报错:属性“name”受保护,只能在类“Person”及其子类中访问。

readonly

ts
class Person {
  readonly name: string;
  constructor(name: string){
    this.name = name;
  }
  setName(){
    this.name = 'a' // 错误:无法分配到 "name" ,因为它是只读属性。
  }
}
new Person('tom').name = 1; // 错误:无法分配到 "name" ,因为它是只读属性。

class Son extends Person{
  constructor(name:string){
    super(name)
  }
}

new Son('son').name = 2 // 错误:无法分配到 "name" ,因为它是只读属性。
  • 参数属性
ts
class Octopus {
  constructor(readonly num: number,public readonly n: string) {
    // this.num = num
  }
  setNum(){
    this.num = 3; // 无法分配到 "num" ,因为它是只读属性。
    this.n = 3; // 无法分配到 "n" ,因为它是只读属性。
  }
}

存取器

类里面可以使用 getter、setter

ts
class Person {
  private _name = 'tom';
  get name():string{
    console.log('get');
    return this._name
  }
  set name(name:string){
    console.log('set');
    this._name = name
    console.log(this._name);
  }
}
console.log(new Person().name);
new Person().name = 'test'

静态属性

ts 静态属性与 ES6 一致

ts
class Person {
  static age:number = 100;
}
Person.age // 100
new Person().age // 不存在

抽象类

B继承A:

  • B ---> 子类[派生类]
  • A ---> 超类[基类、父类]

abstract 关键字表示抽象类(父类),加了 abstract 关键字的方法必须被派生类(子类)继承且实现,不加 abstract 的方法可以不用实现。

ts
/* 父类(抽象类、基类),不会直接被实例化 */
abstract class Person {
  constructor(public name: string,public age: number){}

  /* 子类(派生类必须实现此方法),父类不包含具体实现 */
  abstract getName(num: number):void;

  /* 没有 abstract 子类可以不用实现 */
  getAge(){
    console.log(this.age,'抽象类');
  }
}


class Son extends Person{
  constructor(){
    super('tom',10) // 子类存在构造器时必须调用 super 方法
  }

  /* 实现父类 getName */
  getName(num: number): void{
    console.log(num + this.age);
  }

  myFn(){
    console.log('myFn');
  }
}


new Person(); // 错误 抽象类无法实例化
let p: Person; // 可以创建引用
p = new Son() // 允许子类实例化和赋值
p.getName(1) // ok
p.getAge() // ok
p.myFn(); // 错误:抽象类没有定义

高级技巧

引用 class 声明

ts
class Person {
  static standardGreeting = "Hello";
  greet(): string {
    return Person.standardGreeting;
  }
}
let person: Person = new Person(); // person: Person 需要赋值为 Person 的实例
console.log(person.greet()); // Hello

let newPerson: typeof Person = Person; // 相当于 let newPerson: Person 本身 = Person;
/* 这样就可以在新的引用 newPerson 上使用*/
newPerson.standardGreeting = "Hey";
let person1: Person = new newPerson();
console.log(person1.greet()); // Hey

接口继承类

ts
class _2D {
  x: number | undefined;
  y: number | undefined;
}

interface _3D extends _2D {
  z: number;
}

let point: _3D = { x: 1, y: 2, z: 3 };

评论

交流群