What is the use/advantage of function overloading?
函数重载的用途/优势是什么?
IMO的主要好处是方法/函数命名的一致性,这些方法/函数在逻辑上执行非常相似的任务,并且通过接受不同的参数略有不同。这允许在多个实现中重用相同的方法名。
例如过载:(好)
1 2 3 | function Person[] FindPersons(string nameOfPerson) { ... } function Person[] FindPersons(date dateOfBirth) { ... } function Person[] FindPersons(int age, string dogsName) { ... } |
优于"唯一命名"函数:(更糟)
1 2 3 | function Person[] FindPersonsByName(string nameOfPerson) { ... } function Person[] FindPersonsByDOB(date dateOfBirth) { ... } function Person[] FindPersonsByAgeAndDogsName(int age, string dogsName) { ... } |
这样,编写一个调用/使用这些函数的客户机的编码人员就可以在更高层次的概念思维(我需要找到一个人)下工作,并且不需要记住/定位一个人为的函数名。
对于静态类型,编译器将根据使用参数来匹配适用的重载。对于动态类型,相同的匹配将在运行时发生,如果找不到合适的匹配,可能会导致失败。
非常有效的问题。
您可以在命名上获得一致性,但代价是对精确实现的模糊性。
真正的问题是人类的记忆方法名,对吗?我们找到了它更容易记住的名字是常用。
以及打字的经济性,考虑到更短的方法名?较少不同名字在数学上意味着名字本身包含的信息更少。
这两个问题不应该引起任何关注,因为IDES可以根据前几个字符和参数/返回类型快速查找/猜测/插入方法名。
但我认为,在编码的精确性方面,这是一种成本,也是一种好处。
重载是多态性的一种形式。它允许程序员编写函数在不同类型的数据上在概念上做相同的事情而不改变名称。(它还允许程序员编写函数来根据参数做不同的概念,但这是一个非常糟糕的想法。"
这使得符号的一致性,这对读取和编写代码都很好。I/O是一种非常常见的用途。在大多数常用语言中,有一个函数或运算符将输出任何你喜欢的东西,如EDCOX1、0和C、EDOCX1、1、C++、EDCOX1、2、我以前使用的旧基础,等等。需要
它非常适合C++模板和其他任何构造,在那里你不必知道在编写代码时变量类型是什么。
您的函数可能需要处理一些可选的细节。例如,下面的示例希望向members对象添加一个成员,包括用户知道的任何细节。这里,年龄是创建成员的最小细节,年龄和成员是可选的。[注:代码段中未提供函数定义。]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class Members { public System.Collections.Generic.List<Member> TeamMembers; public AddMember(Member m) {} public AddMember(string name) {} public AddMember(string name, int age) {} public AddMember(string name, int age, string[] memberOf) {} public class Member { public string Name { get; set; } public int Age { get; set; } public string[] MemberOf { get; set; } } } |
您可能希望您的方法适合多种类型的对象。前任。方法可以在控制台上写入空行、bool、int、string、char[]和float等。这是因为函数重载而成为可能的。
函数/方法有时可以采用不同类型的参数来完成它的工作。现在是函数重载的时候了。否则,对于相同的功能,您必须具有不同的功能,这是令人困惑和不好的做法。
- 构造函数是函数,因此可以重载它们。这很方便。
- 当你第一次进入超载时,你很容易变得过于幻想,认为你给未来的开发者带来了好处,给了他们更方便的选择。尽量避免这种情况。不必要的重载可能会混淆未来的开发人员,并导致不必要的代码维护。
即席多态性是很好的东西!!
有时,根据上下文和可用的输入,您有多种方法来完成相同的事情。对于类型严格的静态语言,函数定义可能非常严格,需要提前明确定义。
构造器通常是最好的经典例子。如果您正在构建一个复杂的对象,并且没有所有的部分,那么您仍然希望能够将必须的内容传递给一个构造函数,并让它填充其余部分。您所拥有的可能会有很大的变化,需要以不同的方式定义为构造函数的参数。
它为对象的属性提供同一对象的多个行为。
例如,一种称为EDCOX1〔0〕的方法添加EDCOX1、1和EDCX1 2。
所以定义是:
1 2 3 | int addUs(int a, int b){ return a+b; } |
但是现在,如果您希望参数是类的对象,请说:
1 2 3 4 | class Demo{ int height; int width; } |
您希望同一个函数
所以现在的定义是:
1 2 3 4 5 6 | Demo addUs(Demo a Demo b){ Demo this; this.height = a.height + b.height; this.width = a.width + b.width; return this; } |
它是一种在不同实例上执行不同任务的同名函数机制。我们很容易记住常用的名字。
您可能希望在具有不同参数的代码中执行类似的操作。如果必须给每个函数赋予不同的名称,代码可读性将非常差。