# Java 中的方法重载

> 原文： [https://beginnersbook.com/2013/05/method-overloading/](https://beginnersbook.com/2013/05/method-overloading/)

方法重载是一种功能，如果类的参数列表不同，则允许类具有多个具有相同名称的方法。它类似于 Java 中的[构造函数重载](https://beginnersbook.com/2013/05/constructor-overloading/)，它允许类具有多个具有不同参数列表的构造函数。

让我们回到这一点，当我说参数列表时它意味着方法具有的参数：例如，具有两个参数的方法`add(int a, int b)`的参数列表与方法`add(int a, int b, int c)`的参数列表不同，具有三个参数。

## 重载方法的三种方法

为了重载方法，方法的参数列表必须在以下任何一个方面有所不同：

1.  参数数量。

例如：这是一个有效的重载情况

```java
add(int, int)
add(int, int, int)
```

2.  参数的数据类型。

例如：

```java
add(int, int)
add(int, float)
```

3.  参数的数据类型序列。

例如：

```java
add(int, float)
add(float, int)
```

**方法重载的情况无效：**

当我说参数列表时，我不是在讨论方法的返回类型，例如，如果两个方法具有相同的名称，相同的参数并且具有不同的返回类型，那么这不是一个有效的方法重载示例。这将抛出编译错误。

```java
int add(int, int)
float add(int, int)
```

**方法重载**是[静态多态](https://beginnersbook.com/2013/04/runtime-compile-time-polymorphism/)的一个例子。我们将在单独的教程中讨论[多态](https://beginnersbook.com/2013/03/polymorphism-in-java/)及其类型。

**注意事项：**

1. 静态多态也称为编译时绑定或早期绑定。
2. [静态绑定](https://beginnersbook.com/2013/04/java-static-dynamic-binding/)在编译时发生。方法重载是静态绑定的一个示例，其中方法调用与其定义的绑定在编译时发生。

## 方法重载示例

如本指南开头所述，方法重载是通过使用不同参数声明相同方法来完成的。参数在以下任何一个中都必须不同：参数（或参数）的数量，顺序或类型。让我们看看每个案例的例子。

> 参数列表也称为参数列表

### 示例 1：重载 - 参数列表中的参数数量不同

此示例显示了如何通过具有不同数量的参数来完成方法重载：

```java
class DisplayOverloading
{
    public void disp(char c)
    {
         System.out.println(c);
    }
    public void disp(char c, int num)  
    {
         System.out.println(c + " "+num);
    }
}
class Sample
{
   public static void main(String args[])
   {
       DisplayOverloading obj = new DisplayOverloading();
       obj.disp('a');
       obj.disp('a',10);
   }
}
```

**输出：**

```java
a
a 10
```

在上面的例子中 - 方法`disp()`根据参数的数量重载 - 我们有两个名为`disp`的方法，但它们的参数不同。两者都具有不同数量的参数。

### 示例 2：重载 - 参数的数据类型的差异

在此示例中，方法`disp()`基于参数的数据类型重载 - 我们有两个名为`disp()`的方法，一个使用`char`类型的参数，另一个方法使用`int`类型的参数。

```java
class DisplayOverloading2
{
    public void disp(char c)
    {
        System.out.println(c);
    }
    public void disp(int c)
    {
       System.out.println(c );
    }
}

class Sample2
{
    public static void main(String args[])
    {
        DisplayOverloading2 obj = new DisplayOverloading2();
        obj.disp('a');
        obj.disp(5);
    }
}
```

输出：

```java
a
5
```

### 示例 3：重载 - 参数的数据类型顺序

这里方法`disp()`根据参数的数据类型序列重载 - 这两种方法在参数列表中都有不同的数据类型序列。第一种方法是将参数列表作为`(char, int)`，第二种方法是使用`(int, char)`。由于序列不同，该方法可以过载而没有任何问题。

```java
class DisplayOverloading3
{
   public void disp(char c, int num)
   {
       System.out.println("I’m the first definition of method disp");
   }
   public void disp(int num, char c)
   {
       System.out.println("I’m the second definition of method disp" );
   }
}
class Sample3
{
   public static void main(String args[])
   {
       DisplayOverloading3 obj = new DisplayOverloading3();
       obj.disp('x', 51 );
       obj.disp(52, 'y');
   }
}
```

**输出：**

```java
I’m the first definition of method disp
I’m the second definition of method disp
```

## 方法重载和类型提升

当较小尺寸的数据类型被提升为比这更大的数据类型时称为类型提升，例如：字节数据类型可以提升为`short`，短数据类型可以提升为`int`，`long`，`double`等。

**它与方法重载有什么关系？**

嗯，理解类型提升是非常重要的，否则你会认为程序会抛出编译错误，但实际上程序会因为类型提升而运行正常。

让我们举一个例子，看看我在这里说的是什么：

```java
class Demo{
   void disp(int a, double b){
	System.out.println("Method A");
   }
   void disp(int a, double b, double c){
	System.out.println("Method B");
   }
   public static void main(String args[]){
	Demo obj = new Demo();
	/* I am passing float value as a second argument but
	 * it got promoted to the type double, because there
	 * wasn't any method having arg list as (int, float)
	 */
	obj.disp(100, 20.67f);
   }
}
```

输出：

```java
Method A
```

正如你可以看到我在调用`disp()`方法时传递了`float`值，但它被提升为`double`类型，因为没有任何带参数列表的方法为`(int, float)`。

但是这种类型的促销并不总是发生，让我们看另一个例子：

```java
class Demo{
   void disp(int a, double b){
	System.out.println("Method A");
   }
   void disp(int a, double b, double c){
	System.out.println("Method B");
   }
   void disp(int a, float b){
	System.out.println("Method C");
   }
   public static void main(String args[]){
	Demo obj = new Demo();
	/* This time promotion won't happen as there is
	 * a method with arg list as (int, float)
	 */
	obj.disp(100, 20.67f);
   }
}
```

输出：

```java
Method C
```

如您所见，此时类型提升未发生，因为存在具有匹配参数类型的方法。

**类型升级表：**

左侧的数据类型可以升级为右侧的任何数据类型。

```java
byte → short → int → long
short → int → long
int → long → float → double
float → double
long → float → double

```

## 让我们看几个有效/无效的方法重载案例

情况 1：

```java
int mymethod(int a, int b, float c)
int mymethod(int var1, int var2, float var3)
```

结果：编译时间错误。参数列表完全相同。两种方法都具有相同的数字，数据类型和相同的数据类型序列。

案例 2：

```java
int mymethod(int a, int b)
int mymethod(float var1, float var2)
```

结果：非常好。有效的重载情况。这里参数的数据类型是不同的。

案例 3：

```java
int mymethod(int a, int b)
int mymethod(int num)
```

结果：非常好。有效的重载情况。这里的参数数量不同。

案例 4：

```java
float mymethod(int a, float b)
float mymethod(float var1, int var2)
```

结果：非常好。有效的重载情况。参数的数据类型的顺序是不同的，第一种方法是`(int, float)`，第二种方法是`(float, int)`。

案例 5：

```java
int mymethod(int a, int b)
float mymethod(int var1, int var2)
```

结果：编译时间错误。参数列表完全相同。尽管返回类型的方法不同，但它不是有效的情况。由于方法的返回类型在重载方法时无关紧要。

在程序结束前检查答案之前猜测答案：

**问题 1 - 返回类型，方法名称和参数列表相同。**

```java
class Demo
{
   public int myMethod(int num1, int num2)
   { 
       System.out.println("First myMethod of class Demo");
       return num1+num2;
   }
   public int myMethod(int var1, int var2)
   {
       System.out.println("Second myMethod of class Demo");
       return var1-var2;
   }
}
class Sample4
{
   public static void main(String args[])
   {
       Demo obj1= new Demo();
       obj1.myMethod(10,10);
       obj1.myMethod(20,12);
   }
}
```

**答案：**

它会抛出一个编译错误：不能在同一个类中定义多个具有相同名称和参数列表的方法。

**问题 2 - 返回类型不同。方法名称和参数列表相同。**

```java
class Demo2
{
   public double myMethod(int num1, int num2)
   {
      System.out.println("First myMethod of class Demo");
      return num1+num2;
   }
   public int myMethod(int var1, int var2)
   {
      System.out.println("Second myMethod of class Demo");
      return var1-var2;
   }
}
class Sample5
{
   public static void main(String args[])
   {
      Demo2 obj2= new Demo2();
      obj2.myMethod(10,10);
      obj2.myMethod(20,12);
   }
}
```

**答案：**

它会抛出一个编译错误：即使返回类型不同，也不能在类中给出多个具有相同名称和参数列表的方法。 **方法返回类型在重载的情况下无关紧要。**