版权声明:本文为博主学习记录,分享心得为主,转载前请在评论区留言,谢谢同样爱学习的你。 https://blog.csdn.net/qq_33639584/article/details/54891674
Java方法重载
Java 中,同类中的多个方法用同一个名字,只要参数声明不同即可,这个过程称为方法重载(method overloading )。方法重载是Java 实现多态性的一种方式,是Java 最激动人心,也最有用的特性之一。
对重载的理解
方法重载支持多态性,因为它是Java 实现“一个接口,多个方法”范型的一种方式。但是在不支持方法重载的语言中,每个方法必须有一个唯一的名字。
但是你经常希望实现数据类型不同但本质上相同的方法。
在不支持重载的语言中,通常有这个函数的三个及以上的版本,每个版本都有小差别名字。
例如,在C语言中 参考绝对值函数abs()的例子。
abs ( ) 返回整数的绝对值
labs( ) 返回long 型整数的绝对值( )
fabs( ) 返回浮点值的绝对值
这三个函数实质上是一样的,因为C语言不支持重载,所以每个函数都有自己的名字。
Java 中就不会发生这种情况,因为所有的abs函数可以使用同一个名字。
Java 的标准的类库包含一个abs ( ),math类将abs重载,用于处理数字类型。
Java 可以根据给定参数类型决定调用的abs() 的版本。
重载的价值在于相关的方法使用同一个名字访问。
abs这个名字代表了它执行的通用动作(general action )。
为特别情况选择正确的指定版本是编译器要做的事情。
我们只需要记住执行的通用操作就行了。
通过多态性应用,一个名字就可以了。
从风格上来说,方法重载还暗示了一种关系。
不要使用同一个名字重载无关的方法。
比如:你可以使用sqr这个名字来创建一种方法,该方法返回一个整数的平方根。
可以重载返回一个浮点数值的平方根,但是不要重载返回一个浮点数值的平方值。
因为这种操作在功能上是不同的。违背了它的初衷。
实际编程中,应该只重载相互之间关系紧密的操作。
方法重载的简单例子:
class OverloadDemo {void test() { //定义 test方法
System.out.println("Legend Test");
}
void test(int a) { //第一次重载,带int参test方法,设:输入10}
System.out.println("a: " + a);
}
void test(int a,int b) { //第二次重载,带int双参test方法,设:输入10,20
System.out.println("a andb: " + a + " " + b);
}
double test(double a) { //第三次重载,带double参有返回值 test方法,设:输入123.25
System.out.println("double a:" + a);
return a*a; //(可见重载不受方法的返回类型的影响)
}
class Overload {
public static void main(Stringargs[]) {
OverloadDemo ob = new OverloadDemo();}
ob.test();
ob.test(10);
ob.test(10,20);
ob.test(123.25);
}
该程序产生如下输出:
Legend Test
a: 10
a and b: 10 20
double a: 123.25
从上述程序可见,test()被重载了三次。
定义版本没有参数
第二个版本有一个整型参数
第三个版本有两个整型参数
第四个版本有一个double 型参数。
重载不受方法的返回类型的影响,所以test()第四个版本返回了重载没有因果关系的值。
Java 自匹配方法
当重载的方法被调用时,Java 在调用方法的参数和方法的自变量之间寻找匹配。不过这种匹配并不总是精确的。
在一些情况下,Java 的自动类型转换也适用于重载方法的自变量。
例如,看下面的程序:
class OverloadDemo {
void test() {
System.out.println("Legend Test");
}
void test(int a,int b) {
System.out.println("a andb: " + a + " " + b);
}
void test(double a) {}
System.out.println("Inside test(double) a: " + a);
}
class Overload {
public static void main(String args[]){
OverloadDemo ob = new OverloadDemo();}
int i = 88;
ob.test();
ob.test(10,20);
ob.test(i); // 这个自动转double,因为匹配没有INT,只有double参数方法
ob.test(123.2); // 这个自动转double,因为匹配没有FLOAT,只有double参数方法
}
该程序产生如下输出:
Legend Test
a and b: 10 20
Inside test(double) a: 88
Inside test(double) a: 123.2
在本例中OverloadDemo 没有定义test(int) 。
因此当在Overload 内带整数参数调用test()时,找不到和它匹配的方法。
但是,Java 可以自动地将整数转换为double 型,这种转换就可以解决这个问题。
只有在找不到精确匹配时,Java 的自动转换才会起作用。
【构造函数重载】
除了重载正常的方法外,构造函数也能够重载。实际上大多数你创建的现实的类,重载构造函数是很常见的。
下面是Box类的例子:
class Box {
double width;
double height;
double depth;
Box(double w,double h,double d) {
width = w; height = h;depth= d; //参数值赋值给属性值
}
doublevolume() {}
return width * height * depth; //返回体积的方法
}
在本例中,Box() 构造函数需要三个自变量
所有Box对象必须给Box() 构造函数传递三个参数。
下面的语句在当前情况下是无效的(没有无参方法,需要给定参数值):
Box ob = new Box();
因为Box( )要求有三个参数,所以如果不带参数调用它则是一个错误。
重载Box 构造函数,以适应各种版本。
下面程序是Box 的一个改进版本,它就是运用对Box构造函数的重载来解决这些问题的:
class Box {
double width;
double height;
double depth;
Box(double w,double h,double d) {
width = w;
height = h;
depth = d;
}
Box() {}
width = -1; // use -1 to indicate
height = -1; // an uninitialized
depth = -1; // box
}
Box(double len) {
width = height = depth = len;
}
double volume() {
return width * height * depth;
}
class OverloadCons {
public static void main(String args[]){
double vol;
Box mybox1 = new Box(10,20,15);
Box mybox2 = new Box();
Box mycube = new Box(7);
vol = mybox1.volume();}
System.out.println("mybox1体积:" + vol);
vol = mybox2.volume();
System.out.println("mybox2体积:" + vol);
vol = mycube.volume();
System.out.println("mycube体积:" + vol);
}
该程序产生的输出如下所示:
Volume of mybox1 is 3000.0
Volume of mybox2 is -1.0
Volume of mycube is 343.0