03-TypeScript-泛型和类

2020-10-01  本文已影响0人  低头看云

泛型

 // 需求: 定义一个创建数组的方法, 可以创建出指定长度的数组, 并且可以用任意指定的内容填充这个数组

  let getArray = (value: number, len: number = 5): number[] => {
    return new Array(len).fill(value)
  }
  let r1 = getArray(5, 6)
  console.log('r1', r1)

  // 使用泛型
  let getArray1 = <T>(value: T, len: number = 5): T[] => {
    return new Array(len).fill(value)
  }

  let r2 = getArray1(2)
  console.log('r2', r2) //  自动推导出 r2的类型是number[]
  
  
  let s1 = r2.reduce((acc, cur, index) => {
    return acc + cur
  }, '')
  console.log('s1', s1)

泛型的约束


interface LenInterface {
    length: number
  }

  let getArray2 = <T extends LenInterface>(value: T, len: number = 5): T[] => {
    return new Array(len).fill(value)
  }

  // let arr = getArray2(44)  // 报错  这个泛型函数被定义了约束,因此它不再是适用于任意类型:
  // let arr = getArray2('sssdfd') // 可以
  // 参数中要包含 length 这个属性
  let arr = getArray2({ length: 22, value: '33' })
  console.log('arr', arr)
  // 需求:定义一个函数用于根据指定的key获取对象的value
  let getProps = <T, K extends keyof T>(obj: T, key: K): any => {
    return obj[key]
  }

  let obj = {
    a: '1',
    b: '2',
  }

  let res = getProps(obj, 'b')
  console.log('res', res)
}

 class Person {
    name: string
    age: number
    constructor(name: string, age: number) {
      this.name = name
      this.age = age
    }
    say(): void {
      console.log(`我是名字叫${this.name},年龄是${this.age}`)
    }

    // 静态属性
    static food: string = '泡面'
    // 静态方法
    static eat(): void {
      console.log(`我在吃${this.food}`)
    }
    // 注意:  静态属性和静态方法都是通过 类名.静态方法/ 类名.静态属性 来访问
  }

  let p1 = new Person('css', 18)
  p1.say()
  Person.eat()

  Person.food = '火腿'
  // 类的继承
  class Student extends Person {
    book?: string
    constructor(name: string, age: number, book?: string) {
      super(name, age)
      this.book = book
    }
    say(): void {
      console.log(`我是重写之后的say-${this.name} - ${this.age} - ${this.book}`)
    }

    static eat(): void {
      console.log(`我是重写之后的eat-${this.food}`)
    }
  }

  let stu = new Student('zs', 18, 'js')
  stu.say()
  Student.food = '冰淇淋'
  Student.eat()

类的属性修饰符

class Person {
    // 默认情况下的属性修饰符是 public
    public name: string
    protected age: number // protented 修饰表示 属性是受保护的  只能在类的内部和子类中使用
    private gender: string // private 修饰属性是表示只能在类的内部使用
    constructor(name: string, age: number, gender: string) {
      this.name = name
      this.age = age
      this.gender = gender
    }
    say(): void {
      console.log(`我是名字叫${this.name},年龄是${this.age},性别${this.gender}`)
    }

    // 静态属性
    static food: string = '泡面'
    // 静态方法
    static eat(): void {
      console.log(`我在吃${this.food}`)
    }
    // 注意:  静态属性和静态方法都是通过 类名.静态方法/ 类名.静态属性 来访问
  }
  
  // stuedent继承 Person
  class Student extends Person {
    constructor(name: string, age: number, gender: string) {
      super(name, age, gender)
    }
    say(): void {
      // 属性“gender”为私有属性,只能在类“Person”中访问。
      console.log(`继承---我是名字叫${this.name},年龄是${this.age}`)
    }
  }

  let p2 = new Person('css', 14, '男')
  let stu2 = new Student('ww', 123, 'ss')
  stu2.say()

类方法的修饰符

class Person1 {
    // 默认情况下的属性修饰符是 public
    public name: string
    protected age: number
    private gender: string
    constructor(name: string, age: number, gender: string) {
      this.name = name
      this.age = age
      this.gender = gender
    }
    public say(): void {
      console.log(`我是名字叫${this.name},年龄是${this.age},性别${this.gender}`)
    }

    protected sayAge(): void {
      console.log('age', this.age)
    }

    protected sayGender(): void {
      console.log('gender', this.gender)
    }

    // 静态属性
    static food: string = '泡面'
    // 静态方法
    static eat(): void {
      console.log(`我在吃${this.food}`)
    }
    // 注意:  静态属性和静态方法都是通过 类名.静态方法/ 类名.静态属性 来访问
  }

  let p3 = new Person1('react', 14, '男')
  // 'sayGender' is protected and only accessible within class 'Person1' and its subclasses.
  // p3.sayGender()

类的可选属性

// 类的可选属性
  class Person2 {
    // 在ts中定义了实例属性 那么就必须在构造函数中使用, 否则会报错
    public name: string
    protected age?: number // 可选属性
    private gender?: string
    constructor(name: string, age?: number, gender?: string) {
      this.name = name
      this.age = age
      this.gender = gender
    }
  }

参数属性

  class Person3 {
    constructor(public name: string, public age: number) {
      this.name = name
      this.age = age
    }
  }

  let pp3 = new Person3('r', 22)
  console.log('pp3', pp3)
}

类存取器

const fullNameMaxLength = 10

  class Employee {
    private _fullName: string = ''

    get fullName(): string {
      return this._fullName
    }

    set fullName(newName: string) {
      if (newName && newName.length > fullNameMaxLength) {
        throw new Error('fullName has a max length of ' + fullNameMaxLength)
      }

      this._fullName = newName
    }
  }

  let employee = new Employee()
  employee.fullName = 'Bob'
  if (employee.fullName) {
    console.log(employee.fullName)
  }

抽象类

// 之前的方式创建
  class Base1 {
    name: string
    age: number
    protected constructor(name: string, age: number) {
      this.name = name
      this.age = age
    }
    say(): void {
      console.log(`${this.name} - ${this.age}`)
    }
  }
  class Person1 extends Base1 {
    constructor(name: string, age: number) {
      super(name, age)
    }
  }

  let p1 = new Person1('js', 21)
  p1.say()
  abstract class Base {
    abstract name: string
    abstract say(): void
    eat(): void {
      console.log(this.name, '在吃东西....')
    }
  }

  class Person extends Base {
    name: string = 'css'
    say(): void {
      console.log(`我的名字是${this.name}`)
    }
  }

  let p11 = new Person()
  p11.say()
  p11.eat()

抽象类和接口的区别

类实现接口

interface PersonInterface {
    name: string
    say(): void
  }
  // 只要类实现了某个接口,那么就必须实现接口中所有的属性和方法
  class person implements PersonInterface {
    name: string = 'css'
    say(): void {
      console.log('hello')
    }
  }

接口继承类

  // 接口继承类
  class Person1 {
    name: string = 'css'
    age: number = 24
    say(): void {
      console.log('hello')
    }
  }
  // 一个接口继承了某个类, 那么就会继承这个类中所有的属性和方法
  // 但是只会继承属性和方法的声明, 不会继承属性和方法的实现
  interface PersonInterface1 extends Person1 {
    gender: string
  }

  class Student implements PersonInterface1 {
    name: string = 'js'
    age = 33
    gender: string = '男'
    say(): void {
      console.log('name11111111111:', this.name)
    }
  }
  let stu = new Student()
  stu.say()

  class Person2 {
    name: string = 'css'
    age: number = 24
    protected say(): void {
      console.log('hello222222222222222')
    }
  }
  interface PersonInterface2 extends Person2 {
    gender: string
  }
  class Student1 extends Person2 implements PersonInterface2 {
    name: string = 'js'
    age = 33
    gender: string = '男'
    say(): void {
      console.log('name22222222222222222222:', this.name)
    }
  }

  let stu1 = new Student1()
  stu1.say()

泛型类和接口合并现象

 // 泛型类
  class Chache<T> {
    arr: T[] = []
    add(value: T): T[] {
      this.arr.push(value)
      return this.arr
    }
  }

  let chache = new Chache<number>()
  let res = chache.add(3)
  console.log('res', res)

interface TestInterface {
    name: string
  }

  interface TestInterface {
    age: number
  }

  class Person implements TestInterface {
    name: string = 'zs'
    age: number = 12
  }

上一篇 下一篇

猜你喜欢

热点阅读