三妹开学了,学的计算机软件编程。她学校离我家很近,坐公交车也就 10 站路的距离, 每逢周末她都会来找我,让我辅导她学习 Java。作为一名拥有十余年编程经验的程序员,再加上父母给我们的这份血缘关系,我觉得义不容辞。
“二哥,今天我们要学习的内容是‘方法重载(Overloading)’,对吧?”看来三妹已经提前预习了我上次留给她的作业。
“是的,三妹。如果一个类有多个名字相同但参数个数不同的方法,这就是所谓的方法重载。 ”我面带着朴实无华的微笑回答着她,“如果方法的功能是一样的,但参数不同,使用相同的名字可以提高程序的可读性。”
“假设,你现在需要完成一个加法运算,但参数的个数是不同的,如果你编写一个方法为 a(int i, int j) 进行两个数的相加,编写一个方法为 b(int i,int j, int k) 进行三个数的相加,因为两个方法名是不同的,别的程序员在调用这两个方法的时候就很迷惑,为什么功能相同,名字却不同呢?”
“方法重载刚好能够解决这个问题。”
----正儿八经的分割线,正文开始------------
01、方法重载有哪几种形式
在 Java 中,有两种方式可以达到方法重载的目的:
改变参数的数目;
改变参数的类型。
注意,改变方法的返回类型是不行滴。
1)改变参数的数目
/** * @author 微信搜「沉默王二」,回复关键字 PDF */ public class OverloadingByParamNum { public static void main(String[] args) { System.out.println(Adder.add(10, 19)); System.out.println(Adder.add(10, 19, 20)); } } class Adder { static int add(int a, int b) { return a + b; } static int add(int a, int b, int c) { return a + b + c; } }
在上面的示例中,Adder 类有两个方法,第一个 add 方法有两个参数,第二个 add 方法有三个参数。
2)改变参数的类型
/** * @author 微信搜「沉默王二」,回复关键字 PDF */ public class OverloadingByParamType { public static void main(String[] args) { System.out.println(Adder.add(10, 19)); System.out.println(Adder.add(10.1, 19.2)); } } class Adder { static int add(int a, int b) { return a + b; } static double add(double a, double b) { return a + b; } }
在上面的示例中,Adder 类有两个方法,第一个 add 方法的参数类型为 int,第二个 add 方法的参数类型为 double。
“二哥,改变参数的数目和类型都可以实现方法重载,为什么改变方法的返回值类型就不可以呢?”三妹很能抓住问题的重点嘛。
“因为仅仅改变返回值类型的话,编译器会懵逼。”我略带调皮的口吻回答她。
编译时报错优于运行时报错,所以当两个方法的名字相同,参数个数和类型也相同的时候,虽然返回值类型不同,但依然会提示方法已经被定义的错误。
02、 可以重载 main 方法吗
答案是肯定的,毕竟 main 方法也是个方法,只不过,Java 虚拟机在运行的时候只会调用带有 String 数组的那个 main 方法。
/** * @author 微信搜「沉默王二」,回复关键字 PDF */ public class OverloadingMain { public static void main(String[] args) { System.out.println("String[] args"); } public static void main(String args) { System.out.println("String args"); } public static void main() { System.out.println("无参"); } }
程序输出结果如下所示:
String[] args
03、什么隐式类型转换
由于可以通过改变参数类型的方式实现方法重载,那么当传递的参数没有找到匹配的方法时,就会发生隐式的类型转换。
如上图所示,byte 可以向上转换为 short、int、long、float 和 double,short 可以向上转换为 int、long、float 和 double,char 可以向上转换为 int、long、float 和 double,依次类推。
来看示例:
/** * @author 微信搜「沉默王二」,回复关键字 PDF */ public class OverloadingTypePromotion { void sum(int a, long b) { System.out.println(a + b); } void sum(int a, int b, int c) { System.out.println(a + b + c); } public static void main(String args[]) { OverloadingTypePromotion obj = new OverloadingTypePromotion(); obj.sum(20, 20); obj.sum(20, 20, 20); } }
执行 obj.sum(20, 20) 的时候,发现没有 sum(int a, int b) 的方法,所以此时第二个 20 向上转型为 long,所以调用的是 sum(int a, long b) 的方法。
再来看一个示例:
/** * @author 微信搜「沉默王二」,回复关键字 PDF */ public class OverloadingTypePromotion1 { void sum(int a, int b) { System.out.println("int"); } void sum(long a, long b) { System.out.println("long"); } public static void main(String args[]) { OverloadingTypePromotion1 obj = new OverloadingTypePromotion1(); obj.sum(20, 20); } }
执行 obj.sum(20, 20) 的时候,发现有 sum(int a, int b) 的方法,所以就不会向上转型为 long,调用 sum(long a, long b)。
程序输出结果如下所示:
int
1
继续来看示例:
/** * @author 微信搜「沉默王二」,回复关键字 PDF */ public class OverloadingTypePromotion2 { void sum(long a, int b) { System.out.println("long int"); } void sum(int a, long b) { System.out.println("int long"); } public static void main(String args[]) { OverloadingTypePromotion2 obj = new OverloadingTypePromotion2(); obj.sum(20, 20); } }
当有两个方法 sum(long a, int b) 和 sum(int a, long b),参数个数相同,参数类型相同,只不过位置不同的时候,会发生什么呢?
obj.sum(20, 20) 就会不知道该调用哪一个,对吧?
不明确,很为难,究竟是把第一个 20 从 int 转成 long 呢,还是把第二个 20 从 int 转成 long,智障了!所以,不能写这样让编译器左右为难的代码。
04、ending
“三妹,关于 Java 中的方法重载,我们就学到这里吧,它的用法我相信你一定全部掌握了。”我揉一揉犯困的双眼,疲惫地给三妹说。
“好的,二哥,我这就去练习去。”三妹似乎意犹未尽,这种学习状态真令我感到开心。