1.定义类

class Person{
    constructor(name:string){
        this.name = name;
    }
    name: string;
    getName():void{
        console.log(this.name);
    }
}
let p1 = new Person('fung');
p1.getName();

这个类有3个成员:一个叫做name的属性,一个构造函数和一个getName方法。
我们使用new构造了Person类的一个实例。它会调用之前定义的构造函数,创建一个 Person类型的新对象,并执行构造函数初始化它。
2.存取器
TypeScript支持通过getters/setters来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。

  • 在 TypeScript 中,我们可以通过存取器来改变一个类中属性的读取和赋值行为
  • 构造函数

    • 主要用于初始化类的成员变量属性
    • 类的对象创建时自动调用执行
    • 没有返回值
class Person {
  constructor(name: string) {
    this.myname = name;
  }
  myname: string;
  get name(): string {
    return this.name;
  }
  set name(value) {
    this.name = value;
  }
}
let p1 = new Person("###");
p1.myname = "##++==";
console.log(p1.myname) //##++==

3.参数属性

class User {
    constructor(public myname: string) {}
    get name() {
        return this.myname;
    }
    set name(value) {
        this.myname = value;
    }
}

let user = new User('fung');
console.log(user.name); 
user.name = 'test'; 
console.log(user.name);

仅在构造函数里使用public myname: string参数来创建和初始化name成员。 我们把声明和赋值合并至一处。

参数属性通过给构造函数参数添加一个访问限定符来声明。 使用 public限定一个参数属性会声明并初始化一个公有成员;对于privateprotected来说也是一样。
4.readonly
使用readonly关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。
TypeScript 的类型系统同样也允许将 interface、type、 class 上的属性标识为 readonly
readonly 实际上只是在编译阶段进行代码检查。而 const 则会在运行时检查(在支持 const 语法的 JavaScript 运行时环境中)

class Octopus {
    readonly name: string;
    readonly numberOfLegs: number = 8;
    constructor (theName: string) {
        this.name = theName;
    }
}
let dad = new Octopus("Man with the 8 strong legs");
dad.name = "Man with the 3-piece suit";//err

5.继承

  • 子类继承父类后子类的实例就拥有了父类中的属性和方法,可以增强代码的可复用性
  • 将子类公用的方法抽象出来放在父类中,自己的特殊逻辑放在子类中重写父类的逻辑
  • super可以调用父类上的方法和属性
class Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  getName(): string {
    return this.name;
  }
  setName(value: string): void {
    this.name = value;
  }
}

class Student extends Person {
  no: number;
  constructor(name: string, age: number, no: number) {
    super(name, age);
    this.no = no;
  }
  getNo():number{
    return this.no;
  }
}

let student1 = new Student('fung', 18, 20190807);
console.log(student1); //Student { name: 'fung', age: 18, no: 20190807 }

6.类里的修饰符(public protected private)

class Father {
  public name: string;   //类里面 子类 其它任何地方外边都可以访问
  protected age: number; //类里面 子类 都可以访问,其它任何地方不能访问
  private money: number; //类里面可以访问, 子类和其它任何地方都不可以访问
  constructor(name: string, age: number, money: number) {
    this.name = name;
    this.age = age;
    this.money = money;
  }
  getName(): string {
    return this.name;
  }
  setName(value: string): void {
    this.name = value;
  }
}

class Child extends Father {
  constructor(name: string, age: number, money: number) {
    super(name, age, money);
  }
  desc() {
    console.log(`${this.name} ${this.age} ${this.money}`); //Erro 属性“money”为私有属性,只能在类“Father”中访问。
  }
}
let child = new Child('zfpx',10,1000);
console.log(child.name);
console.log(child.age);  //属性“age”受保护,只能在类“Father”及其子类中访问。
console.log(child.money);//属性“money”为私有属性,只能在类“Father”中访问。

7.静态属性/静态方法
我们在类里定义的属性,如果没有使用static修饰,则都是类的实例的属性,仅当类被实例化的时候才会被初始化。静态属性和静态方法都是类的属性和类的方法。
使用的时候需要加类名使用。

class Animal {
  static className = "Animal";
  static getClassName(){
    return Animal.className;
  }
  public name:string;
  constructor(name:string){
    this.name = name
  }
  getName(): string{
    return this.name;
  }
}
console.log(Animal.className);
console.log(Animal.getClassName());

ts被编译后的代码如下

var Animal = /** @class */ (function () {
    function Animal(name) {
        this.name = name;
    }
    Animal.getClassName = function () {
        return Animal.className;
    };
    Animal.prototype.getName = function () {
        return this.name;
    };
    Animal.className = "Animal";
    return Animal;
}());
console.log(Animal.className);
console.log(Animal.getClassName());

8.装饰器

  • 装饰器是一种特殊类型的声明,它能够被附加到类声明、方法、属性或参数上,可以修改类的行为
  • 常见的装饰器有类装饰器、属性装饰器、方法装饰器和参数装饰器
  • 装饰器的写法分为普通装饰器和装饰器工厂

(1)类装饰器
类装饰器在类声明之前声明,用来监视、修改或替换类定义

function enhancer(target: any) {
    target.prototype.name = 'fung';
    target.prototype.age = 18;
    target.prototype.eat = function(){
      console.log('eat');
    }
  }
  interface Person{
    name:string;
    age:number;
    eat:any
  }
  @enhancer
  class Person {
    constructor() {}
  }

  let p:Person = new Person();
  console.log(p.name);
  p.eat();

9.抽象类

  • 抽象描述一种抽象的概念,无法被实例化,只能被继承
  • 无法创建抽象类的实例
  • 抽象方法不能在抽象类中实现,只能在抽象类的具体子类中实现,而且必须实现
abstract class Aminal{
    name!: string;
    abstract speak():void
  }
  class Cat extends Aminal{
    speak(){
      console.log('miaomiao');
    }
  }

  let cat = new Cat();
  cat.speak();//miaomiao

image.png
10.抽象类 VS 接口

  • 不同类之间公有的属性或方法,可以抽象成一个接口(Interfaces)
  • 而抽象类是供其他类继承的基类,抽象类不允许被实例化。抽象类中的抽象方法必须在子类中被实现
  • 抽象类本质是一个无法被实例化的类,其中能够实现方法和初始化属性,而接口仅能够用于描述,既不提供方法的实现,也不为属性进行初始化
  • 一个类可以继承一个类或抽象类,但可以实现(implements)多个接口
  • 抽象类也可以实现接口
abstract class Animal{
    name:string;
    constructor(name:string){
      this.name = name
    }
    abstract speak():void;
  }

  interface Animal{
    fly():void
  }

  class Dog extends Animal implements Animal{
    speak(){
      console.log('wangwang');
    }
    fly(){
      console.log('i can jump,can not fly.')
    }
  }

  let dog = new Dog('huangmao');
  dog.fly();
  dog.speak();

11.抽象方法

  • 抽象类和方法不包含具体实现,必须在子类中实现
  • 抽象方法只能出现在抽象类中
  • 子类可以对抽象类进行不同的实现
abstract class Animal {
    abstract speak(): void;
  }
  class Dog extends Animal {
    speak() {
      console.log("小狗汪汪汪");
    }
  }
  class Cat extends Animal {
    speak() {
      console.log("小猫喵喵喵");
    }
  }
  let dog = new Dog();
  let cat = new Cat();
  dog.speak();
  cat.speak();

12.重写(override) VS 重载(overload)

  • 重写是指子类重写继承自父类中的方法
  • 重载是指为同一个函数提供多个类型定义
class Animal {
    speak(word: string): string {
      return "动作叫:" + word;
    }
  }
  class Cat extends Animal {
    speak(word: string): string {
      return "猫叫:" + word;
    }
  }
  let cat = new Cat();
  console.log(cat.speak("hello"));
  //--------------------------------------------
  function double(val: number): number;
  function double(val: string): string;
  function double(val: any): any {
    if (typeof val == "number") {
      return val * 2;
    }
    return val + val;
  }

  let r = double(1);
  console.log(r);

13.继承 VS 多态

  • 继承(Inheritance)子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
  • 多态(Polymorphism)由继承而产生了相关的不同的类,对同一个方法可以有不同的行为
class Animal {
    speak(word: string): string {
      return "Animal: " + word;
    }
  }
  class Cat extends Animal {
    speak(word: string): string {
      return "Cat:" + word;
    }
  }
  class Dog extends Animal {
    speak(word: string): string {
      return "Dog:" + word;
    }
  }
  let cat = new Cat();
  console.log(cat.speak("hello"));
  let dog = new Dog();
  console.log(dog.speak("hello"));

大煜儿
106 声望7 粉丝

用心走路,给每一个细节打一个结。