Name conflict inside a class when there's multiple inheritance of interfaces containing the same method name, but different return types

huangapple go评论62阅读模式
英文:

Name conflict inside a class when there's multiple inheritance of interfaces containing the same method name, but different return types

问题

我有两个接口A和B它们都有一个名为`myFunction`的函数接口A的函数返回类型是`void`接口B的函数返回类型是`string`

当类C实现了A和B多重继承会在类C中出现冲突因为我们不能实现两个名为`myFunction`但返回类型不同的函数如何正确地实现/避免这种模式

interface A {
  myFunction: () => void;
}

interface B {
  myFunction: () => string;
}

class C implements A, B {
  myFunction() {
    console.log('asd');
  }
  myFunction() {
    return 'asd';
  }
}

new C().myFunction();
英文:

I have two interfaces, A and B, and they both have a function named myFunction. Interface A's function has a return type of void and interface B's function has a return type of string.

When Class C implements both A and B (multiple inheritance), there is a conflict in class C since we can’t have to implement two functions named myFunction with different return types. What is the correct approach to implement/avoid such patterns?

interface A {
  myFunction: () => void;
}

interface B {
  myFunction: () => string;
}

class C implements A, B {
  myFunction() {
    console.log('asd');
  }
  myFunction() {
    return 'asd';
  }
}

new C().myFunction();

答案1

得分: 1

你只需在继承自接口的所有抽象方法中编写一个函数以处理逻辑,并在此处使用 function overload。阅读更多关于 Function overload

interface A {
  myFunction: (val: string) => void;
  otherFunc: (val: string, options: string) => void;
}

interface B {
  myFunction: (val: number) => string;
  otherFunc: (val: string, options: string, otherParam: any[]) => string;
}

class C implements A, B {
  otherFunc(val: string, options: string): void;
  otherFunc(val: string, options: string, otherParam: any[]): string;
  otherFunc(...args: any[]): void | string {
    // args may be is [val, options] or [val, options, otherParam];
    // business logic depend on args and check args[2] (otherParam) for doing more thing.
    if (args[2] && args[2].length > 1) {
      // implement business logic for interface B
    }
    return '';
  }

  myFunction(val: string): void;
  myFunction(val: number): string;
  myFunction(val: string | number): void | string {
    // business logic depend on val
    return val ? console.log(val) : val.toString();
  }
}
英文:

You only just do logic in one function for all abstract method that inheritance from interface and use function overload at here. Read more Function overload

interface A {
  myFunction: (val: string) => void;
  otherFunc: (val: string, options: string) => void;
}

interface B {
  myFunction: (val: number) => string;
  otherFunc: (val: string, options: string, otherParam: any[]) => string;
}

class C implements A, B {
  otherFunc(val: string, options: string): void;
  otherFunc(val: string, options: string, otherParam: any[]): string;
  otherFunc(...args: any[]): void | string {
    // args may be is [val, options] or [val, options, otherParam];
    // business logic depend on args and check args[2] (otherParam) for doing more thing.
    if (args[2] && args[2].length > 1) {
      // implement business logic for interface B
    }
    return '';
  }

  myFunction(val: string): void;
  myFunction(val: number): string;
  myFunction(val: string | number): void | string {
    // business logic depend on val
    return val ? console.log(val) : val.toString();
  }
}

答案2

得分: -1

在你描述的情景中,当实现具有冲突函数签名(不同的返回类型)的多个接口(A和B)时,没有直接解决冲突的方法。在大多数编程语言中,不允许有相同名称但返回类型不同的两个函数。

为了解决这个问题,你可以考虑以下方法:

  1. 重命名函数:将接口A和B中的一个或两个函数重新命名,使它们具有不同的名称。这样,实现中就不会有冲突。

    JavaScript:

    interface A {
    myFunctionA: () => void;
    }

    interface B {
    myFunctionB: () => string;
    }

    class C implements A, B {
    myFunctionA() {
    console.log('asd');
    }
    myFunctionB() {
    return 'asd';
    }
    }

    new C().myFunctionA();
    new C().myFunctionB();

  2. 使用组合而不是继承:不要直接在类C中实现两个接口,而是创建分别实现每个接口的单独类,然后使用组合将它们组合在一起。

    TypeScript:

    interface A {
    myFunction: () => void;
    }

    interface B {
    myFunction: () => string;
    }

    class AImplementation implements A {
    myFunction() {
    console.log('asd');
    }
    }

    class BImplementation implements B {
    myFunction() {
    return 'asd';
    }
    }

    class C {
    private aImplementation: AImplementation;
    private bImplementation: BImplementation;

    constructor() {
    this.aImplementation = new AImplementation();
    this.bImplementation = new BImplementation();
    }

    myFunctionA() {
    this.aImplementation.myFunction();
    }

    myFunctionB() {
    return this.bImplementation.myFunction();
    }
    }

    new C().myFunctionA();
    new C().myFunctionB();

通过使用组合,你可以将每个接口的实现分离到不同的类中,并在类C内部相应地委托函数调用。

根据你的应用程序的具体需求,选择最适合你的方法。

英文:

In the scenario you described, when implementing multiple interfaces (A and B) with conflicting function signatures (different return types), there is no direct way to resolve the conflict. Having two functions with the same name but different return types is not allowed in most programming languages.

To overcome this issue, you can consider the following approaches:

Rename the functions: Rename one or both of the functions in interfaces A and B to have distinct names. This way, there will be no conflict in the implementation.

JavaScript:

  interface A {
  myFunctionA: () => void;
}

interface B {
  myFunctionB: () => string;
}

class C implements A, B {
  myFunctionA() {
	console.log('asd');
  }
  myFunctionB() {
	return 'asd';
  }
}

new C().myFunctionA();
new C().myFunctionB();

Use composition instead of inheritance: Instead of implementing both interfaces directly in class C, you can create separate classes that implement each interface and then use composition to combine them.

TypeScript:

interface A {
  myFunction: () => void;
}

interface B {
  myFunction: () => string;
}

class AImplementation implements A {
  myFunction() {
	console.log('asd');
  }
}

class BImplementation implements B {
  myFunction() {
	return 'asd';
  }
}

class C {
  private aImplementation: AImplementation;
  private bImplementation: BImplementation;

  constructor() {
	this.aImplementation = new AImplementation();
	this.bImplementation = new BImplementation();
  }

  myFunctionA() {
	this.aImplementation.myFunction();
  }

  myFunctionB() {
	return this.bImplementation.myFunction();
  }
}

new C().myFunctionA();
new C().myFunctionB();

By using composition, you can separate the implementation of each interface into distinct classes and delegate the function calls accordingly within the class C.

Choose the approach that best suits your needs based on the specific requirements of your application.

huangapple
  • 本文由 发表于 2023年7月3日 09:24:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76601369.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定