详解:Java的重载方法与示例

方法重载是一项功能,如果一个类的参数列表不同,则它允许一个类拥有多个具有相同名称的方法。它类似于Java中的构造函数重载,它允许一个类具有多个具有不同参数列表的构造函数。

让我们回到重点,当我说参数列表时,它表示方法具有的参数:例如,具有两个参数的方法add(int a,int b)的参数列表与方法add的参数列表不同(int a,int b,int c)具有三个参数。

 

重载方法的三种方法

为了重载方法,方法的参数列表必须在以下两个方面有所不同:
1.参数数量。
例如:这是重载的有效情况

add(int, int)
add(int, int, int)

 

2.参数的数据类型。
例如:

add(int, int)
add(int, float)

3.参数的数据类型顺序。
例如:

add(int, float)
add(float, int)

方法重载的无效情况:
当我说参数列表时,我不是在说方法的返回类型,例如,如果两个方法具有相同的名称,相同的参数并且具有不同的返回类型,那么这不是有效的方法重载示例。这将引发编译错误。

int add(int, int)
float add(int, int)

方法重载是静态多态性一个示例。我们将在单独的教程中讨论多态性及其类型。

注意事项:
1. 静态多态也称为编译时绑定或早期绑定。
2. 静态绑定发生在编译时。方法重载是静态绑定的一个示例,其中方法调用对其定义的绑定发生在编译时。

方法重载示例

如本指南开头所讨论的,方法重载是通过声明具有不同参数的相同方法来完成的。参数必须在以下两个方面有所不同:参数(或参数)的数量,顺序或类型。让我们看一下每种情况的示例。

参数列表也称为参数列表

示例1:重载–参数列表中的参数数量不同

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

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);
   }
}

输出:

a
a 10

在上面的示例中-方法disp()根据参数数量而重载-我们有两种方法的名称,disp但它们具有的参数不同。两者都有不同数量的参数。

示例2:重载–参数数据类型的差异

在此示例中,方法disp()基于参数的数据类型进行了重载–我们有两种名称为disp()的方法,一种具有char类型的参数,另一种具有int类型的参数。

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);
    }
}

输出:

a
5

例3:重载–参数的数据类型顺序

在此,disp()根据参数的数据类型顺序重载方法–两种方法在参数列表中都有不同的数据类型顺序。第一种方法的参数列表为(char,int),第二种方法的参数为(int,char)。由于顺序不同,因此该方法可以重载而不会出现任何问题。

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');
   }
}

输出:

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

方法重载和类型提升

例如,当将较小大小的数据类型提升为大于此大小的数据类型称为类型提升时,例如:字节数据类型可以提升为short,short数据类型可以提升为int,long,double等。

它与方法重载有什么关系?
好吧,了解类型提升非常重要,否则您会认为程序会引发编译错误,但实际上由于类型提升,程序可以正常运行。
让我们举个例子看看我在这里说什么:

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);
   }
}

输出:

Method A

如您所见,我在调用disp()方法时传递了float值,但是由于没有任何参数列表为(int,float)的方法,它被提升为double类型。

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

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);
   }
}

输出:

Method C

如您所见,由于存在一个具有匹配参数类型的方法,因此没有发生这种类型的升级。
类型提升表:
左侧的数据类型可以提升为右侧的任何数据类型。

byte → short → int → long
short → int → long
int → long → float → double
float → double
long → float → double

让我们看看方法重载的几种有效/无效情况

情况1:

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

结果:编译时错误。参数列表完全相同。两种方法具有相同的编号,数据类型和相同的数据类型序列。

情况2:

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

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

情况3:

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

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

情况4:

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

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

情况5:

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

结果:编译时错误。参数列表完全相同。即使方法的返回类型不同,也不是有效的情况。因为重载方法时方法的返回类型无关紧要。

在程序末尾检查之前,请先猜测答案:
问题1 –返回类型,方法名称和参数列表相同。

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 –返回类型不同。方法名称和参数列表相同。

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);
   }
}

答案:
它将引发编译错误:一个类中不能给出多个具有相同名称和参数列表的方法,即使它们的返回类型不同。在重载的情况下,方法返回类型无关紧要。

  • 71
    点赞
  • 138
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论
// 对overload测试的文件:OverloadTest.java public class OverloadTest { // 下面几个方法用来验证可以通过定义不同的参数类型和参数的数目进行方法重载。 public void fun(){ System.out.println("method fun in OverloadTest, no parameter"); } public void fun(float f) { System.out.println("method fun in OverloadTest, parameter type: float"); } public void fun(int i){ System.out.println("method fun in OverloadTest, parameter type: int"); } public void fun(int i1, int i2) { System.out.println("method fun in OverloadTest, parameter type: int, int"); } // 下面的两个方法用来验证可以通过定义不同的参数顺序进行方法重载。 // 需要注意:这里的参数肯定不是相同的类型,否则的顺序的先后就毫无意义。 public void fun1(int i, float f) { System.out.println("method fun1 in OverloadTest, sequence of parameters is: int, float"); } public void fun1(float f, int i) { System.out.println("method fun1 in OverloadTest, sequence of parameters is: float, int"); } // 下面的两个方法用来验证方法抛出的异常对于重载的影响. // 无论是异常的类型还是异常的个数都不会对重载造成任何的影响。 public void fun2() throws TestException { System.out.println("fun2 in OverloadTest, exception: TestException"); } public void fun2(int i) throws TestException, TestException1 { System.out.println("fun2 in OverloadTest, exception: TestException, TestException1"); } public void fun2(float f) throws Exception { System.out.println("fun2 in OverloadTest, exception: Exception"); } // 不能通过抛出的异常类型来重载fun方法。 //public void fun(int i) throws Exception { // System.out.println("method fun in OverloadTest, parameter type: int, exception: Exception"); //} // ? 不能通过返回值重载fun方法。 //public boolean fun(int i) throws Exception { // System.out.println("method fun in OverloadTest, parameter type: int, exception: Exception, return: boolean"); // return true; //} private void fun3() { } // 不能通过不同的访问权限进行重载 public void fun3() { } public static void main(String[] args) { // 这里只是定义了OverloadTest的实例,所以test不会调用 // OverloadTest1中的方法。 OverloadTest test = new OverloadTest1(); // 这里定义了OverloadTest1的实例,因为OverloadTest1是OverloadTest // 的子类,所以test1会调用OverloadTest中的方法。 OverloadTest1 test1 = new OverloadTest1(); try { int i = 1, j = 2, m = 3; // 这里不会调用OverloadTest1的fun方法 // test.fun(i, m, j); test1.fun(i, j, m); test1.fun(); // 这个调用不会执行,因为fun3()在OverloadTest中访问权限是priavte //test1.fun3(); test1.fun3(i); } catch(Exception e) { } } } class OverloadTest1 extends OverloadTest{ // 在子类中重载fun public void fun(int i, int m, int n) { System.out.println("Overload fun1 in OverloadTest1, parameter type: int, int, int"); } // 这个不是对父类中方法重载,只是一个新的方法。 public void fun3(int i) { System.out.println("fun2 in OverloadTest1"); } } // 对override测试的文件:OverrideTest.java public class OverrideTest { public void fun() throws TestException { System.out.println("method fun in OverrideTest"); } private void fun1() { System.out.println("method fun1 in OverrideTest"); } public static void main(String[] args) { OverrideTest test = new OverrideTest1(); try { test.fun(); test.fun1(); } catch(Exception e) { } } } class OverrideTest1 extends OverrideTest{ // 以下正常Override public void fun() throws TestException2 { System.out.println("fun in OverrideTest1"); } // 不能Override父类中的方法,因为它定义了不同的异常类型和 // 返回值。 //public int fun() throws TestException1 { // System.out.println("method fun in Test"); // return 1; //} // 不能Override父类中的方法,因为它抛出了比父类中非法范围 // 更大的异常。 //public void fun() throws Exception { // System.out.println("fun in OverrideTest1"); //} // 这个方法并没有Override父类中的fun1方法,因为这个方法在 // 父类是private类型,所以这里只是相当于定义了一个新方法。 public void fun1() { System.out.println("method fun1 in Test"); } } class TestException extends Exception{ public TestException(String msg) { super(msg); } } class TestException1 extends TestException { public TestException1(String msg) { super(msg); } } class TestException2 extends TestException { public TestException2(String msg) { super(msg); } }
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_陈哈哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值