1.方法签名

一个方法由访问控制、返回类型、方法名、参数列表以及方法体组成,而其中的方法名和参数列表称为方法签名,它唯一地标识出某个方法。

2.方法重载

    方法重载发生在方法名相同,而参数列表不同时。

public class OverloadDemo {
static void f(String name, int i) {
System.out.println("String:" + name + " int:" + i);
}
static void f(String name, float f) {
System.out.println("String:" + name + " float:" + f);
}
static void f(int i, String name) {
System.out.println("int:" + i + " String:" + name);
}
/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
f("xingfeng", 23);
f("xingfeng", 23.0f);
f(23, "xingfeng");
}
}
public class OverloadDemo {
static void f(String name, int i) {
System.out.println("String:" + name + " int:" + i);
}
static void f(String name, float f) {
System.out.println("String:" + name + " float:" + f);
}
static void f(int i, String name) {
System.out.println("int:" + i + " String:" + name);
}
/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
f("xingfeng", 23);
f("xingfeng", 23.0f);
f(23, "xingfeng");
}
}

Output:

String:xingfeng int:23
String:xingfeng float:23.0
int:23 String:xingfeng

可以看到参数列表顺序不同也可以发生重载。

或许我们有时会想为什么不能通过返回值区分重载方法呢?

比如下面两个方法.虽然它们有同样的名字和形参列表,但却很容易区分它们:

void f(){}
int f(){return 1;}

只要编译器可以根据语境明确判断出语义,比如在int x=f()中,那么确实可以区分重载方法。不过,有时你并不关心返回值,这时就不能区分了,所以为了这些避免这些麻烦。编辑器是不允许这样的情况发生的,因为方法签名唯一地标识出一个方法,而如果仅仅只是让返回值不同,编辑器会认为是同一个方法,所以会提示错误。

我们知道可以用可变参数列表作为形参,那当有可变参数列表时,重载方法是如何进行区分的呢?

public class OverloadDemo {
static void f(String name, int i) {
System.out.println("String:" + name + " int:" + i);
}
static void f(String name, int... i) {
System.out.println("String:" + name + " int...:" + i[0] + " " + i[1]);
}
/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
f("xingfeng", 23);
f("xingfeng", 23, 12, 45);
}
}
public class OverloadDemo {
static void f(String name, int i) {
System.out.println("String:" + name + " int:" + i);
}
static void f(String name, int... i) {
System.out.println("String:" + name + " int...:" + i[0] + " " + i[1]);
}
/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
f("xingfeng", 23);
f("xingfeng", 23, 12, 45);
}
}

Output:

String:xingfeng int:23
String:xingfeng int...:23 12

执行f("xingfeng",23)时尽管两个方法都可以,但是还是执行了没有可变参数列表的那个方法,所以我们也就知道了在有可变参数列表方法重载时,Java会执行没有可变参数的那个方法。

3.方法覆盖

方法覆盖发生在继承语法中,当继承基类时,导出类就会拥有基类的方法,有时我们可能需要给某个方法新的操作,这时就需要用到方法覆盖。即导出类重写了那个方法,所以导出类和基类就拥有不同的实现了。

public class OverrideDemo {
/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
Parent parent = new Parent();
System.out.println(parent.name());
Son son = new Son();
System.out.println(son.name());
}
}
class Parent {
String name() {
return "Parent name()";
}
}
class Son extends Parent {
String name() {
return "Son name()";
}
}
public class OverrideDemo {
/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
Parent parent = new Parent();
System.out.println(parent.name());
Son son = new Son();
System.out.println(son.name());
}
}
class Parent {
String name() {
return "Parent name()";
}
}
class Son extends Parent {
String name() {
return "Son name()";
}
}

Output:

Parent name()
Son name()

4.总结

     方法签名(方法名和参数列表)唯一地标识出一个方法,所以编译器通过检查是否方法签名唯一来判断一个新的方法是否可以被创建。

       方法重载:方法名相同,参数列表不同;当与有可变参数列表方法发生重载时,优先调用没有可变参数列表的方法。

       方法覆盖发生在继承语法中,导出类需要给从基类中继承过来的方法新的实现时。