为什么我应该重载方法?

我在我的重载方法书中发现了两个例子,但是它并没有清楚地解释为什么它是有用的:

package keepo; public class Main{ public static void main(String [] args) { int newScore = calculateScore("Tim", 500); System.out.println("New Score is" + newScore); calculateScore(75); } public static int calculateScore(String playerName, int score){ System.out.println("Player" + playerName +"Has score" + score); return score * 1000; } public static int calculateScore(int score){ System.out.println("Unnamed player scored" + score + "points"); return score * 1000; } } 

这很简单,但老实说,在这里重载方法似乎是无用的,而且似乎只是为了这样做而做的。

本书的下一个例子是方法重载,这似乎更有用,因为这个程序计算英尺到厘米,有一种方法,你可以放在脚和英寸,一种方法,你可以把英寸。 但是,对于这两种方法来说,看起来还是很容易的。

这就是说,这样做有没有真正的好处? (我读过这个 ,但是我不是很满意,看起来很简单。)

我想如果你谈论函数/方法重载的真正好处,那么没有它的东西你不会绕过,那么就像你在你的问题中指出的一样,你不会find任何东西。

但是它有帮助吗? 我们来考虑一下这个例子。

假设我正在制作一个应用程序,用他的名字find一个人,然后我声明并定义一个方法

 public Person[] findPerson(String name) 

现在我们得到一个要求,我们必须根据他的出生datefind一个人,所以引入一个新的方法

 public Person[] findPerson_byDOB(Date date) 

让我们假设这继续下去,我们的应用程序中有很多方法。

 public Person[] findPerson(String name) public Person[] findPerson_byDOB(Date date) public Person[] findPerson_byAddress(Address address) public Person[] findPerson_bySSN(SSN ssn) public Person[] findPerson_byDepartment(Department department) public Person[] findPerson_byMobile(Mobile mobile) 

这只是一个部分; 当我们被要求引入多个参数时,这可以继续

 public Person[] findPerson_byMobileAndAddress(Mobile mobile, Address address) public Person[] findPerson_byAddressAndDepartment(Address address, Department department) public Person[] findPerson_byDOBAndDepartment(DOB dob, Department, department) public Person[] findPerson_byAddressAndDOB(Address address, DOB dob) 

和许多更多…

虽然这看起来有些夸张,但相信我,在制定实际的行业级应用程序时,我们可能会遇到这样的情况,当我们得到上百种这样的方法时,最终我们需要一个所有这些方法的目录他们究竟做了什么

这实际上是一个噩梦,当我们不得不使用它的时候,我们必须find所有这些方法的名字。

但是,当所有参数不同时,我们可以给函数赋予相同的名称,并且真的变得非常容易记住。

 public Person[] findPerson(String name) public Person[] findPerson(Date date) public Person[] findPerson(Address address) public Person[] findPerson(SSN ssn) public Person[] findPerson(Department department) public Person[] findPerson(Mobile mobile) public Person[] findPerson(Mobile mobile, Address address) public Person[] findPerson(Address address, Department department) public Person[] findPerson(DOB dob, Department, department) public Person[] findPerson(Address address, DOB dob) 

现在大卫在他的回答中指出,我们都知道如何获得整数的String值; 可能我们已经在某处读过了。

 static String.valueOf(new Integer(1)); 

但是你知道还有多less方法是用同一个名字重载吗?

 static String.valueOf(boolean b) static String.valueOf(char c) static String.valueOf(char[] data) static String.valueOf(double d) static String.valueOf(float f) static String.valueOf(int i) static String.valueOf(long l) static String.valueOf(Object obj) 

好处是你不必记住所有的东西。 你甚至不用猜,因为它一直是同一个名字。


编辑 根据Namnodorel的build议

考虑这个PrintStream类的重载方法。

 void println() void println(boolean x) void println(char x) void println(char[] x) void println(double x) void println(float x) void println(int x) void println(long x) void println(Object x) void println(String x) 

如果我们必须写下来,请考虑一下可读性:

 void println_emptyLine() void println_boolean(boolean x) void println_character(char x) void println_characterArray(char[] x) void println_double(double x) void println_float(float x) void println_integer(int x) void println_long(long x) void println_object(Object x) void println_string(String x) 

当您使用不同types的值执行相同操作的方法时,重载非常有用。

Math课提供了一个完美的例子 – 它有function过载的types – 四个abs ,四min ,四个max ,等等:

 int max(int a, int b) {...} float max(float a, float b) {...} long max(long a, long b) {...} double max(double a, double b) {...} 

没有重载的替代方法会迫使你将types“编码”为你的方法的名字,例如Math.intMax(a, b) ,这对用户代码的可读性是有害的。

简单而简洁:重载只是由Java提供的一种可能性(但大多数现代和灵活的语言都使用它) (和其他语言,如C ++或C#),以允许开发人员创build相同的方法/函数名称,它。

为什么?
因为方法命名是重要的,方法命名应该传达它的行为。 所以,如果两个方法具有相同的行为(例如转换为string),但是一个使用long作为input,而另一个使用int作为input,为什么使用不同的方法名?

  String myString = String.valueOf(new Integer(1)); String myOtherString = String.valueOf(new Long(2)); 

意图和目标是一样的,只是input参数的改变。

当重载是有意义的,你应该使用它,而不是创build一些变体笨拙的名字。

方法重载在以下情形中很有用:

考虑你有一个跟踪名单列表的类。 你有上面的代码样式,每个方法都有自己的对这个名字列表的操作。

突然间,列表的内部表示发生了变化(可能从一个array到一个ArrayList ,这并不重要)。 你想成为一个负责重构的人吗? 单身 。 方法?

方法重载是有用的,因为那么你可以通过一个单一的generics方法来路由所有的操作。 这意味着每当内部表示发生变化时,您只需更改该generics方法,而其他所有专用方法的工作方式仍然相同。


另外,考虑你提供的例子。 如果你想改变程序如何打印信息会发生什么? 你将不得不修改两种方法来打印相同types的消息,这是一个维护的噩梦。 当然,现在看起来很小,但是想想你的项目在何时发展,并且你开始有更多的方法依赖于这个(有效的)消息格式。

我是一个对象,我有能力,能力是固定的,但可以接受各种参数。

如果能力可以接受1000种参数,你是否想绞尽脑汁考虑1000个能力名称?

把别人的post作为一个重载的好习惯,拿JNIEnv做为不好的做法,因为C不支持重载。

 CallStaticObjectMethod, CallStaticObjectMethodV, CallStaticObjectMethodA, CallStaticBooleanMethod, CallStaticBooleanMethodV, CallStaticBooleanMethodA, CallStaticByteMethod, CallStaticByteMethodV, CallStaticByteMethodA, CallStaticCharMethod, CallStaticCharMethodV, CallStaticCharMethodA, CallStaticShortMethod, CallStaticShortMethodV, CallStaticShortMethodA, CallStaticIntMethod, CallStaticIntMethodV, CallStaticIntMethodA, CallStaticLongMethod, CallStaticLongMethodV, CallStaticLongMethodA, CallStaticFloatMethod, CallStaticFloatMethodV, CallStaticFloatMethodA, CallStaticDoubleMethod, CallStaticDoubleMethodV, CallStaticDoubleMethodA, CallStaticVoidMethod, CallStaticVoidMethodV, CallStaticVoidMethodA, 

Reger到JNI以获得更详细的结构定义

超载的另一个原因是提供一个或多个默认参数。

考虑以下:

 class Something { // Imagine that this is a real class, that does real work. public void doSomething(boolean b, char c, double d, int i) { // Imagine that this is one of the main components of class Something. System.out.println("Hi. You passed: " + b + ", " + c + ", " + d + ", and " + i + "."); } public void doSomething(boolean b, char c, double d) { doSomething(b, c, d, 42); } public void doSomething(boolean b, char c) { doSomething(b, c, 1.3579); } public void doSomething(boolean b) { doSomething(b, 'q'); } public void doSomething() { doSomething(true); } } 

在这个例子中,每个重载提供了其中一个参数的默认值,将它们链接在一起,直到完全调用实际完成工作的doSomething()版本。

 Something s = new Something(); Something t = new Something(); Something u = new Something(); // ... s.doSomething(true, 'c', 2.9); t.doSomething(false, 'z'); u.doSomething(); 

看这里的例子。