十、java中的重载

来源:互联网 发布:电信网络报维修 编辑:程序博客网 时间:2024/04/30 03:00
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


0 0
原创粉丝点击