TypeScript学习笔记系列二(类)

426 阅读2分钟

思维导图

定义:同一类的东西放在一起(进行归类)

class Animal {}

构造器:初始化类

class Animal {
    constructor(){}
}

属性:存放特征

class Animal {
  name: string;
  foot: number;
  hair: boolean;
}

函数:操作

class Animal {
    walk() {}
}

修饰符:

访问
  1. public:共有(默认,外部可以使用)
  2. private:私有(只有类内部可以使用,子类不能使用)
  3. protected:受保护(只有类内部/子类可以使用)
publicprivateprotecte
子类×
实例化××

使用原则:最小访问原则

  1. 尽量private,所有属性都是private。
  2. 极少量protected,尽量小心
  3. 需要public,一律是方法
只读成员

readonly:只读成员(只能在属性初始化/构造器中进行赋值,可以互相修改)

静态成员

static:静态成员(可以直接从类本身获取到,不可从实例中获取到,只能在属性初始化/类本身进行赋值),常用于类的公用例如:Math.PI

class Animal {
  // 构造器
  constructor(name: string, foot: number, hair: boolean, head: number) {
    this.name = name;
    this.foot = foot;
    this.hair = hair;
    // 只能在属性初始化/构造器中进行赋值(可以互相修改)
    this.head = head;
    // 只能在属性初始化/类本身进行赋值(this是实例化)
    Animal.color = 'blue'
  };

  // 属性初始化
  public name: string;
  private foot: number;
  protected hair: boolean;
  readonly head: number;
  static color: string = 'red';

  // 函数
  walk() {
    // this.foot/this.hair可以被访问到,因为在内部使用
    console.log(`name:${this.name};foot:${this.foot};hair:${this.hair}`);
  }
}

// 静态成员可以直接从类本身获取到
console.log(Animal.color);

const a = new Animal('horse', 4, true, 1);

// // 静态成员不可以从实例中获取到
// console.log(a.color);

a.walk();

// // a.foot/a.hair不可以被访问到
// console.log(`name:${a.name};foot:${a.foot};hair:${a.hair}`);

class Horse extends Animal {
  walk2() {
    // this.foot不可以被访问到,因为在只能在内部使用
    // this.hair 可以被访问到,因为它属于子类
    console.log(`name:${this.name};foot:${this.foot};hair:${this.hair}`);
  }
}

访问器:添加拦截条件,保证数据合规

// 编译需要设置为ES5,ts --target ES5 xxx.ts
class Animal {
  private _foot: number = 2;
  
  // get/set不需要都设置
  public get foot() {
    return this._foot;
  }
  public set foot(num: number) {
    if (num > -1) {
      this._foot = num;
    } else {
      throw new Error('foot必须大于-1');
    }
  }
}

const a = new Animal();
console.log(a.foot);

a.foot = 4;
console.log(a.foot);

类的继承:从基类开始,继承所有的属性和函数,派生一个新的派生类

class Animal {
  // 属性
  public name: string = 'cat';

  public weChat() {
    console.log('eagleChinaWu');
  }
}

class Horse extends Animal {
  public name = 'horse';
  public age: number = 2;

  // public weChat() {
  //   console.log('weChat:eagleChinaWu');
  // }
}

// let h = new Horse();
// // console.log(`name: ${h.name};age: ${h.age}`);

// h.weChat();

let a = new Animal();
let h = new Horse();

let d: Animal;
d = h;

function getName(a: Animal) {
  console.log(a.name);
};

getName(h);

一个派生类实例,同时也是基类的实例

class Animal {
  public name: string;

  constructor(name: string) {
    this.name = name;
  }
}

class Horse extends Animal {
  public age: number;

  // 参数必须要有基类的参数
  constructor(name: string, age: number) {
    // 先初始化基类
    super(name)

    // 再初始化派生类
    this.age = age;
  }
}

抽象类:作为基类使用,为所有的派生类,提供一些通用的函数,自身无法使用、由派生类实现具体函数

abstract class Sharp {
  abstract area(): number;

  abstract erimeter(): number;
}

class Circle extends Sharp {
  public radius: number;

  constructor(radius: number) {
    super();

    this.radius = radius;
  }

  area(): number {
    return Math.PI * this.radius * this.radius;
  }

  erimeter(): number {
    return 2 * this.radius * Math.PI;
  }
}

// // 抽象类不能直接实例化
// let s = new sharp();

let c = new Circle(66);
console.log(c.area());
console.log(c.erimeter());

abstract class Quadrangle extends Sharp {
  public points: number[];
}

class Rectangle extends Sharp {
  public width: number;
  public height: number;

  constructor(width: number, height: number) {
    super();

    this.width = width;
    this.height = height;
  }

  area() {
    return this.width * this.height;
  }

  erimeter() {
    return (this.width + this.height) * 2;
  }
}

// let s: Sharp;

// s = new Circle(66);
// s = new Rectangle(66, 88);

// s.area();

// function draw(sharp: Sharp) {
//   sharp.area();
// }

function drawCircle(circle: Circle) {}

function drawRectangle(rectangle: Rectangle) {}