Java中方法重载的确切需求

Java中方法重载的确切需求,java,overloading,Java,Overloading,因为我已经找到了很多关于方法重载的例子和结论,但我仍然对我们如何实时使用它感到困惑 首先,方法重载是一个类级别的活动,这意味着在该类中,我们正在重载一个名称相同但参数不同的方法,如 void sum(int a,int b){System.out.println(a+b);} void sum(double a,double b){System.out.println(a+b);} 在我们调用这个方法之后 public static void main(String args[]){

因为我已经找到了很多关于方法重载的例子和结论,但我仍然对我们如何实时使用它感到困惑

首先,方法重载是一个类级别的活动,这意味着在该类中,我们正在重载一个名称相同但参数不同的方法,如

void sum(int a,int b){System.out.println(a+b);}  
void sum(double a,double b){System.out.println(a+b);} 
在我们调用这个方法之后

public static void main(String args[]){  
ClassName obj=new ClassName ();  
obj.sum(10.5,10.5);  
obj.sum(20,20);  
}  
void method1(int a,int b){System.out.println(a+b);}  
void method2(double a,double b){System.out.println(a+b);} 
假设我将采用两种不同的方法

public static void main(String args[]){  
ClassName obj=new ClassName ();  
obj.sum(10.5,10.5);  
obj.sum(20,20);  
}  
void method1(int a,int b){System.out.println(a+b);}  
void method2(double a,double b){System.out.println(a+b);} 
我将调用与上面相同的两种方法

public static void main(String args[]){  
ClassName obj=new ClassName (); 
obj.method1(20,20);   
obj.method2(10.5,10.5);  
} 
在这两种情况下,对于这两种方法,活动是相同的,那么在这种情况下,重载/多态性的确切需求是什么呢

在某个地方我发现方法重载增加了程序的可读性任何人都可以指定,只有因为这一行,我们才使用方法重载


谢谢

假设Java中没有方法重载

而不是:

System.out.println("String");
System.out.println(5);
System.out.println('c');
...
我们会:

System.out.printlnString("String");
System.out.printlnInt(5);
System.out.printlnChar('c');
...
甚至更糟的是:

System.out.println1("String");
System.out.println2(5);
System.out.println3('c');
...

这两种选择都会降低代码的可读性。

您可以检查现有的Java API,如
Math
数组
,以查看重载的威力

您想记住每个方法名称取决于您的数据类型,还是只使用Arrays.sort()并让语言本身根据参数决定应该使用哪个实现

Arrays.sortByte(byte[] abyte)

Arrays.sortChar(char[] ac)

Arrays.sortFloat(float[] af)

Arrays.sortDouble(double[] ad)

Arrays.sortShort(short[] as)

Arrays.sortInt(int[] ai)

Arrays.sortLong(long[] al)
对于其他一些场景,您可能有几十个具有相同功能的方法,但实现只是根据几十个参数的组合略有不同,如果不使用重载,情况会变得更糟

同样的讨论已经在这篇文章中讨论过了


方法重载还可以帮助API设计人员提供不同级别的抽象

例如,她可以选择提供一个初学者版本,其中大多数参数都是默认值,在大多数情况下都能正常工作,同时提供一个专家版本,用户可以微调参数以满足其特定需求:

/*
 * A beginner version that just works.
 */
public void foo() {
    foo(1, 2);
}

/*
 * An expert version where the user has more control over the
 * parameters, requiring more knowledge about the API.
 */
public void foo(int a, int b) {
}
来自
HashMap.java
的真实示例:

/**
 * Constructs an empty <tt>HashMap</tt> with the specified initial
 * capacity and load factor.
 *
 * @param  initialCapacity the initial capacity
 * @param  loadFactor      the load factor
 * @throws IllegalArgumentException if the initial capacity is negative
 *         or the load factor is nonpositive
 */
public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal initial capacity: " +
                                           initialCapacity);
    if (initialCapacity > MAXIMUM_CAPACITY)
        initialCapacity = MAXIMUM_CAPACITY;
    if (loadFactor <= 0 || Float.isNaN(loadFactor))
        throw new IllegalArgumentException("Illegal load factor: " +
                                           loadFactor);
    this.loadFactor = loadFactor;
    this.threshold = tableSizeFor(initialCapacity);
}

/**
 * Constructs an empty <tt>HashMap</tt> with the specified initial
 * capacity and the default load factor (0.75).
 *
 * @param  initialCapacity the initial capacity.
 * @throws IllegalArgumentException if the initial capacity is negative.
 */
public HashMap(int initialCapacity) {
    this(initialCapacity, DEFAULT_LOAD_FACTOR);
}

/**
 * Constructs an empty <tt>HashMap</tt> with the default initial capacity
 * (16) and the default load factor (0.75).
 */
public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
/**
*构造具有指定初始值的空哈希映射
*容量和负载系数。
*
*@param initialCapacity初始容量
*@param loadFactor荷载系数
*如果初始容量为负,@将引发IllegalArgumentException
*或者负载系数是非正的
*/
公共HashMap(int initialCapacity,float loadFactor){
如果(初始容量<0)
抛出新的IllegalArgumentException(“非法初始容量:”+
初始容量);
if(初始容量>最大容量)
初始容量=最大容量;

如果(loadFactor,这里有一个例子,说明为什么像我们这样的开发人员需要方法重载才能有效地使用它们:

java中的Graphics2D类中有一个名为drawImage的方法,尽管它有一个重载,如下所示: 抽象空绘图图像(BuffereImage img、BuffereImage op op、int x、int y) 抽象图像(图像img、仿射变换、图像观察者obs)

假设它们被标记为drawImage1和drawImage2,而不是如下图所示进行组织,这将使任何版本的drawImage都有一个完全不同的名称供您记住,这意味着您可能最终不得不记住每个drawImage方法的许多名称,而不是简单地知道哪些参数e可以接受。
因此,方法重载为开发人员提供了具有不同功能但名称相同的不同方法,因为它们基本上做相同的事情,但需要不同的参数来完成,就像drawImage重载一样。

您可以在oracle文档页面中找到有关方法的更多详细信息

假设您有一个类,该类可以使用书法绘制各种类型的数据(字符串、整数等),并且包含用于绘制每种数据类型的方法

为每个方法(例如drawString、drawInteger、drawFloat等)使用新名称很麻烦

在Java编程语言中,您可以对所有绘图方法使用相同的名称,但向每个方法传递不同的参数列表。
因此,数据绘图类可以声明四个名为draw的方法,每个方法都有不同的参数列表。

文档页面中提供的注释与您的语句正好相反(重载增加了代码的可读性)

注意:重载方法应该谨慎使用,因为它们会使代码的可读性大大降低

请看一个例子

Assume that you have to shift a Shape by its parameters : length, width and height.
Square
将其长度作为参数传递

矩形
将其长度和宽度作为参数传递

另一个3D形状
传递其长度、宽度和高度

    public void shiftPosition(int length){
        shiftPosition(length,0,0);
    }
    public void shiftPosition(int length,int width){
        shiftPosition(length,width,0);
    }
    public void shiftPosition(int length, int width, int height){
        System.out.println("Shfit Position by length:width:height:"+
        length+":"+width+":"+height);
    }
sifhtPosition
是一个具有三个不同签名的重载方法

假设有一个场景,同一方法有8个不同版本。 如果您试图在项目类中找到每个方法的引用以进行代码重构,您会发现这是一个大混乱


这篇文章解释了方法重载的成本和不利之处。

必须添加数字后缀,这会破坏抽象。由于技术限制,您需要方法名称来描述方法的功能,而不是命名。更不用说制作伪“可选”参数,例如
foo(Bar)
foo(Bar,Baz)
可以,但这是一个API级设计,但实时性与我们使用方法重载的Web应用程序类似。@ranjan在声明自己的方法时应用相同的参数。如果您有做类似事情但使用不同参数的方法(不同类型的参数或不同数量的参数),有时给他们取一个相同的名字是有意义的。