static void f3(short x) { prt("f3(short)"); }
static void f3(int x) { prt("f3(int)"); }
static void f3(long x) { prt("f3(long)"); }
static void f3(float x) { prt("f3(float)"); }
static void f3(double x) { prt("f3(double)");}
static void prt(String s) {
System.out.println(s);
}
方法的重载(有的翻译成过载)就是方法名相同,方法的参数序列不相同(这里不是指继承关系中的重写):
1)仅仅是返回类型不同,不能重载;这在一般编程语言中都是这样规定的,原因非常简单,根据返回类型确定要调用那个方法,
需要根据返回值的接受者类型来确定,这在很多时候都是非常困难的(例如接受类型是Object,或者不需要接收返回值的情况)。
2)参数序列的不同主要是指参数类型序列的不同,而不是参数名字的不同;
3)在确定参数类型不同时,不会考虑继承关系,虽然ClassA是ClassB的父类,下面:
public String DoSomething(ClassA A)和public String DoSomething(ClassB B)是符合重载的.
对于重载需要注意以下:
1)对于主类型(基本类型)重载,如果调用时实参是变量或者指定了类型的常数(2.0d),或者常数的类型唯一确定(字符,字符串,布尔),
则根据变量类型来选择要调用的方法,但对于实参是常数,不易确定的数字类型,在没有明确类型标记的情况下,一般整数会转换成int型,
一般小数会被转换成double,测试如下:
//调用测试:
char a='A';
f3(a);
f3(1);
//f3(10000000000);出错
f3(10000000000l);
f3(2.0);
f3(2.0f);
f3(2.0d);
测试结果:
f3(int)
f3(int)
f3(long)
f3(double)
f3(float)
f3(double)
2)对于有继承关系的类型形成的重载,调用的时候也是根据变量类型来确定调用方法的,只不过,如果当前变量类型没有,则寻着父类型方向
向上寻找,直到找到为止(肯定会找到,如果找不到编译的时候就会报错):
下面的MyClassA->D依次为父子关系,下面是重载方法:
public class OverloadClass {
public void DoSomething(MyClassA a)
{
System.out.println("MyClassA a:"+a.getClass().getName());
}
public void DoSomething(MyClassB b)
{
System.out.println("MyClassB b:"+b.getClass().getName());
}
public void DoSomething2(MyClassA a)
{
System.out.println("MyClassA a:"+a.getClass().getName());
}
public void DoSomething2(MyClassC c)
{
System.out.println("MyClassC c:"+c.getClass().getName());
}
public void DoSomething3(MyClassC c)
{
System.out.println("MyClassC c:"+c.getClass().getName());
}
}
重载测试代码:
OverloadClass theOC = new OverloadClass();
MyClassA theA = new MyClassA();
MyClassB theB = new MyClassB();
MyClassA theC = new MyClassC();
MyClassB theD = new MyClassC();
MyClassC theE = new MyClassD();
MyClassD theF = new MyClassD();
//theOC.DoSomething(theA);
//theOC.DoSomething(theB);
//theOC.DoSomething(theC);
theOC.DoSomething2(theA);
theOC.DoSomething2(theB);
theOC.DoSomething2(theC);
theOC.DoSomething2(theD);
theOC.DoSomething2(theE);
theOC.DoSomething2(theF);
//theOC.DoSomething3(theA);//编译错误.
这种重载判断规则,同样也适用于C#.之所以重载是根据变量类型而不是实际类型来判断,其实原因非常简单,因为重载是在编译期就
会确定的,这个时候变量类型也是确定的,因此比较好判断,而实际类型往往是在运行期间才知道,编译期的重载当然不可能根据运行期
的事情来确定(这也是强类型语言的一个优势和劣势)。
PS:构造函数也可以重载。注意如果在构造函数中调用另外一个构造函数一定要放在构造函数的第1行,且只能调用一次。这个规定在C#中
也是一样,只是书写语法不一样。