跳到主要内容

重载

2023年06月27日
柏拉文
越努力,越幸运

一、方法重载


1.1 优势

  1. 结构分明,让代码可读性,可维护性提升许多,而且代码更漂亮
  2. 各司其职,自动提示方法和属性,每个重载方法完成各自的功能,输出取值时不用强制转换就能出动自动提示,从而提高开发效率。
  3. 更利于功能扩展

1.2 规则

方法重载 一组具有相同的名字,不同的参数列表、不同的返回值的方法。

方法签名 方法签名 = 方法名称 + 方法参数个数 + 方法参数类型 + 返回值类型 四者合成。在TypeScript中,包含了实现签名重载签名实现签名是一种方法签名,重载签名也是一种方法签名。

完整的方法重载定义规则如下:

  • 规则1: 由一个实现签名 + 一个或多个重载签名合成
  • 规则2: 外部调用方法重载定义的方法时,只能调用重载签名,不能调用实现签名。这是因为实现签名下的方法体是给重载签名编写的,实现签名只是在定义时起到了统领所有重载签名的作用,在执行调用时就看不到实现签名了。
  • 规则3: 调用重载方法时,会根据传递的参数来判断你调用的是哪一个方法
  • 规则4: 只有一个方法体,只有实现签名配备了方法体,所有的重载签名都只有签名,没有配备方法体。
  • 规则5: 关于参数类型规则完整总结如下:
    • 无论重载签名由几个参数、参数是何种类型,实现签名都可以是一个无参方法签名
    • 实现签名参数个数可以少于重载签名的参数个数,但实现签名如果准备包含重载签名的某个位置的参数,那实现签名就必须兼容所有重载签名该位置的参数类型
  • 规则6: 关于重载签名和实现签名的返回值类型规则完整总结如下:
    • 必须给重载签名提供返回值类型,TypeScript 无法默认推导
    • 提供给重载签名的返回值类型不一定为其执行时的真实返回值类型,可以为重载签名提供真实返回值类型,也可以提供 void 或 unknown 或 any 类型。如果重载签名的返回值类型是 void 或 unknown 或 any 类型,那么将由实现签名来决定重载签名执行时的真实返回值类型。当然为了调用时能有自动提示+可读性更好+避免可能出现了类型强制转换,强烈建议为重载签名提供真实返回值类型。
    • 不管重载签名返回值类型时何种类型,实现签名都可以返回 any 类型 或者 unknown 类型,当然一般我们两者都不选择,让 TypeScript 默认为实现签名自动推导返回值类型

1.3 场景

  • 实现 JavaScript 版的 ArrayList

    class ArrayList {
    constructor(public element: Array<object>) {

    }
    get(index: number) {
    return this.element[index];
    }
    show() {
    this.element.forEach((ele) => {
    console.log(ele);
    });
    }
    remove(value: number): number
    remove(value: object): object
    remove(value: number | object): number | object {
    this.element = this.element.filter((ele, index) => {
    if (typeof value === 'number') {
    return index !== value;
    } else {
    return value !== ele;
    }
    });
    return value;
    }
    }

    const one = {
    id: 1,
    name: '哈哈'
    }
    const two = {
    id: 2,
    name: '嘻嘻'
    }
    const three = {
    id: 3,
    name: '呵呵’'
    }
    const array = [one, two, three]
    const newArrayList = new ArrayList(array);
    newArrayList.remove(1);
    newArrayList.show();
    newArrayList.remove(three);
    newArrayList.show();

二、构造器重载


2.1 优势

  1. 结构分明,让代码可读性,可维护性提升许多,而且代码更漂亮
  2. 各司其职,自动提示方法和属性,每个重载方法完成各自的功能,输出取值时不用强制转换就能出动自动提示,从而提高开发效率。
  3. 更利于功能扩展

2.2 规则

构造器重载 一组具有相同的名字,不同的参数列表、不同的返回值的构造器。

构造器签名 构造器签名 = 构造器名称 + 构造器参数个数 + 构造器参数类型 + 返回值类型 四者合成。在TypeScript中,包含了实现签名重载签名实现签名是一种构造器签名,重载签名也是一种构造器签名。

完整的构造器重载定义规则如下:

  • 规则1: 由一个实现签名 + 一个或多个重载签名合成
  • 规则2: 外部调用构造器重载定义的构造器时,只能调用重载签名,不能调用实现签名。这是因为实现签名下的构造器体是给重载签名编写的,实现签名只是在定义时起到了统领所有重载签名的作用,在执行调用时就看不到实现签名了。
  • 规则3: 调用重载构造器时,会根据传递的参数来判断你调用的是哪一个构造器
  • 规则4: 只有一个构造器体,只有实现签名配备了构造器体,所有的重载签名都只有签名,没有配备构造器体。
  • 规则5: 关于参数类型规则完整总结如下:
    • 无论重载签名由几个参数、参数是何种类型,实现签名都可以是一个无参构造器签名
    • 实现签名参数个数可以少于重载签名的参数个数,但实现签名如果准备包含重载签名的某个位置的参数,那实现签名就必须兼容所有重载签名该位置的参数类型

构造器时是方法吗?

对象调用的才是方法,但是TypeScript 构造器是在对象空间地址赋值给对象变量之前被调用,而不是用来被对象变量调用的。构造器 可以说成是构造函数,但不能被看成是一个方法。

构造器有返回值吗?

TypeScript 构造器 会隐式的返回this

构造器重载的意义

构造器重载函数重载 使用基本相同,主要区别是: TypeScript 类构造器重载签名和实现签名都不需要管理返回值。TypeScript 类 只可以定义一个构造器,如果有用到多个构造器的场景,需要用构造器重载来解决。

2.3 场景

  • 多种场景下求面积

    type ParamsType = {
    width:number;
    height:number;
    }

    class Square{
    public width:number;
    public height:number;
    constructor(width:number,height:number)
    constructor(value:ParamsType)
    constructor(value:number | ParamsType,height:number = 0){
    if(typeof value === 'number'){
    this.width = value;
    this.height = height;
    }else{
    this.width = value.width;
    this.height = value.height;
    }
    }
    getArea(){
    return this.width * this.height;
    }
    }

    const s1 = new Square(30,40);
    console.log(s1.getArea());

    const s2 = new Square({width:30,height:40});
    console.log(s2.getArea());