关于方法重载是什么,以及怎么进行重载,这些我们目前先不去研究,先来看看以下代码不使用方法重载机制,存在哪些缺点?
public static void main(String[] args) {
int x1 = 10;
int x2 = 20;
int retValue1 = sumInt(x1 , x2);
System.out.println(x1 + "+" + x2 + "=" + retValue1);
long y1 = 10L;
long y2 = 20L;
long retValue2 = sumLong(y1 , y2);
System.out.println(y1 + "+" + y2 + "=" + retValue2);
double z1 = 10.0;
double z2 = 20.0;
double retValue3 = sumDouble(z1, z2);
System.out.println(z1 + "+" + z2 + "=" + retValue3);
}
public static int sumInt(int a , int b){
return a + b;
}
public static long sumLong(long a , long b){
return a + b;
}
public static double sumDouble(double a , double b){
return a + b;
}
运行结果如下图所示:
图7-12:没有重载,分析缺点
我们可以看到以上三个方法功能“相似”,都是求和,只不过参与求和的数据类型不同,因此定义了三个方法,分别起了三个不同的方法名。这种方式会增加程序员编程的压力,因为程序员起码要记忆三个方法名,另外代码也不是很美观。怎么解决呢?我们来看看使用方法重载机制之后会是怎样,请看以下代码以及运行结果:
public static void main(String[] args) {
int x1 = 10;
int x2 = 20;
int retValue1 = sum(x1 , x2);
System.out.println(x1 + "+" + x2 + "=" + retValue1);
long y1 = 10L;
long y2 = 20L;
long retValue2 = sum(y1 , y2);
System.out.println(y1 + "+" + y2 + "=" + retValue2);
double z1 = 10.0;
double z2 = 20.0;
double retValue3 = sum(z1, z2);
System.out.println(z1 + "+" + z2 + "=" + retValue3);
}
public static int sum(int a , int b){
return a + b;
}
public static long sum(long a , long b){
return a + b;
}
public static double sum(double a , double b){
return a + b;
}
运行结果如下图所示:
图7-13:使用重载机制
以上代码使用了方法重载机制,我们可以看到,三个“功能相似”的方法名字都叫做sum,只不过方法的形参不同,这样对于程序员来说,调用方法时所需要记忆的方法名更少一些,代码更加美观一些。
接下来我们正式的研究一下方法的重载机制:什么是方法重载?什么情况下我们考虑使用方法重载?在代码角度来看,满足什么条件的时候构成方法重载?
那么,什么是方法重载呢?方法重载(overload)是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数。调用重载方法时,Java编译器能通过检查调用的方法的参数类型和个数选择一个恰当的方法。方法重载通常用于创建完成一组任务相似但参数的类型或参数的个数不同的方法。调用方法时通过传递给它们的不同个数和类型的实参来决定具体使用哪个方法。
什么情况下我们考虑使用方法重载呢?在同一个类当中,如果多个功能是相似的,可以考虑将它们的方法名定义的一致,使用方法重载机制,这样便于程序员的调用,以及代码美观,但相反,如果两个方法所完成的功能完全不同,那么方法名也一定要不一样,这样才是合理的。
代码满足什么条件的时候构成方法重载呢?满足以下三个条件:
● 在同一个类当中。
● 方法名相同。
● 参数列表不同:个数不同算不同,顺序不同算不同,类型不同也算不同。
接下来我们来看看以下程序哪些方法构成了方法重载,哪些没有:
图7-14:哪些方法重载了,哪些没有
编译结果如下图所示:
图7-15:编译错误信息提示
通过观察以上代码以及测试结果我们得知,方法5和方法4是一样的,这不是方法重载,这叫“方法重复(哈哈)”,因为之前我们就说过方法形参中起决定性作用的是参数的数据类型,参数的名字随意,因为每一个形参都是局部变量,变量名自然是随意的。其中方法6和方法1相同,显然方法的重载和方法的返回值类型没有关系,这也是合理的,因为之前我们提过,方法执行结束之后的返回值我们可以接收也可以不接收。另外方法7和方法1也无法构成重载,显然方法重载和修饰符无关。
总之,方法1和方法2要想构成方法重载,首先它们在同一个类当中,方法名一样,参数列表不同(类型、个数、顺序),这样java虚拟机在运行的时候就可以分清楚去调用哪个方法了。其实,最终要调用哪个方法,还是取决于调用的时候传递的实际参数列表。所以在java编程中要区分两个方法,首先看方法名,如果方法名一致,则继续看它们的形式参数列表。
接下来我们来看一下方法重载在实际开发中的应用,你有没有觉得每一次输出的时候“System.out.println();”这行代码很麻烦,我们来封装一个工具类,请看以下代码:
public class U {
public static void p(){
System.out.println();
}
public static void p(int data){
System.out.println(data);
}
public static void p(long data){
System.out.println(data);
}
public static void p(float data){
System.out.println(data);
}
public static void p(double data){
System.out.println(data);
}
public static void p(boolean data){
System.out.println(data);
}
public static void p(char data){
System.out.println(data);
}
public static void p(String data){
System.out.println(data);
}
}
public class UTest {
public static void main(String[] args) {
U.p("hello world!");
U.p(10);
U.p(9.0);
U.p(false);
U.p('国');
int a = 10;
int b = 20;
int c = a + b;
U.p(a + "+" + b + "=" + c);
}
}
运行结果如下图所示:
图7-16:测试工具类U
看到以上的代码,你是不是感觉以后要打印数据到控制台就很方便了,代码再也不需要写这么多“System.out.println();”,你只需要“U.p();”,当然,你需要把U.java文件编译生成的U.class文件拷贝到你的硬盘当中,一直携带着,什么时候需要的话,把U.class文件放到classpath当中就可以使用了。