TS的使用笔记(二)

121 阅读3分钟

对象的基本概念

面向对象

对象 = 数据(属性)+ 功能(方法)组成,在程序中,一切皆对象。

  • window 对象 ---> 操作浏览器;
  • document 对象 ---> 操作网页;
  • console 对象 ---> 操作控制台;

对象的模型,决定对象的结构。

class Dog {
  name: string
  age: number


  // 构造函数会在对象创建时调用,初始化
  // this 指的是当前的实例
  constructor(name: string, age: number) {
    this.name = name,
    this.age = age
  }

  // 在实例方法中,this 指向的是当前实例(谁调用指向谁)
  say() {
    console.log(`${this.name}: 汪汪汪!`);
  }
}

const dog = new Dog('小黑', 3)
console.log(dog);
dog.say()

继承和super关键字

继承的基本使用

class Animal{

     name: string

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

     say() {
      console.log('动物在叫');
     }
    }

    class Dog extends Animal {
    
      age: number
        
      // 因为 constructor 也是一个方法,子类与父类同名的方法会被重写,所以要用 super 调用父类
      constructor(name:string, age: number) {
        super(name) // super 是超类,指的就是父类
        this.age = age
      }


      say() {
        console.log('汪汪汪!');
        super.say() // 调用父类的方法
      }
    }

    const dog = new Dog('小白', 4)
    console.log(dog);
    dog.say()

抽象类和抽象方法

  • 如果,不希望父类也能被 new 出来,那么需要在 class 前加 abstract,使其变成抽象类;
  • 抽象方法:
    • 抽象方法用 abstract 开头,没有方法体;
    • 抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写;
    • abstract say():void

接口

接口:用来定义一个类结构,用来定义一个类中应该有的属性和方法,同时接口也可以当类型声明使用。

  • 与类型声明不同点:
    • 类型声明不可以重复声明,但是接口可以;
    • 接口可以在定义类的时候去限制类的结构,接口中的所有属性都不能有实际的值,只定义对象结构,在接口中所有的方法都是抽象方法。
interface myInter {
    name: string
    say():void
    }
  • 定义类时,可以用 implements 关键字使类实现一个接口
    • 限制类必须复合规范
class Myclass implements myInter{
      name: string

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

      say() {
        console.log('大家好!');
      }
    }

属性封装

避免属性被直接修改,而采用get 和 set 对属性进行存取和修改。

/*
  public: 属性可以在任意地方被访问(修改),默认值
  private: 私有属性,只能在类的内部进行访问(修改)
    - 通过在类中添加方法使得私有属性可以被外部访问。
  protected: 受包含的属性,只能在类及子类中进行访问,不能通过实例访问
*/

class A {

  private _name: string
  protected _age: number

  constructor(name:string, age: number) {
    this._name = name
    this._age = age
  }

  get name() {
    return this._name
  }


  set name(value:string) {
    this._name = value
  }
}

const a = new A('张三', 12)

a.name = '王五' // 默认调用了 set 方法

console.log(a);

泛型

在定义函数或类时,如果遇到类型不明确就可以使用泛型

function fn<T>(a: T): T {
  return a
}

// 直接调用
let res = fn(10)

// 手动指定
let res2 = fn<string>('hello')

// 给泛型指定范围
interface Inter{
  length: number
}

// T extends Inter 表示泛型 T 必须使 Inter 实现类(子类)
function fn2<T extends Inter>(a: T): number{
  return a.length
}

// 类中使用泛型
class Myclass<T>{
  name: T
  constructor(name: T) {
    this.name = name
  }
}

const m1 = new Myclass<string>('张三')