一、重载
重载:Java里允许同一个类里定义多个同名方法,只要形参列表不同就行。如果同一个类中包含了两个或者两个意思方法的方法名相同,则被成为方法重载。
方法重载要求:
a) 同一个类中方法名相同,
b) 参数列表不同,
至于方法的其他部分,如方法返回值类型、修饰符等,与方法重载没有任何关系。
下面看一个简单的代码:
public class Main {
public void test(){
System.out.println("无参数");
}
public void test(String str){
System.out.println("有参数" + str);
}
public static void main(String[] args) {
Main m = new Main();
m.test();
m.test("HelloWorld");
}
}
输出:
无参数
有参数HelloWorld
从上面的代码中,我们可以看到在同一个Main类中,包含了两个同名的方法test,但是由于两个test方法形式参数不同,所以这里就是方法重载的一种体现了。
可能有人会疑惑,为什么不能用返回值来区分重载方法呢?
比如下面两个方法,虽然它们有相同的名字和参数,但是却很容易区分。
void test(){}
int test(){return 1;}
如果是类似
int x = test();
那么的确很容易根据此语境区分两个方法。
但是!!!有时候人会区分,编译器却不能区分出来,比如像下面的调用方法:
test();
这个时候编译器就糊涂了,不知道该调用哪个test(); 因此,根据方法返回值来区分重载方法是行不通的。
二、不定参数
从JDK1.5之后,Java允许定义形参个数可变的参数,如果在定义方法时,在最后一个形参的类型后增加三点(...),则表明该形参可以接受多个参数值,有了可变参数,当你指定参数时,编译器实际上会为你去填充数组,你获取的仍是一个数组,多个参数值会被当成数组传入。
public class Main {
public void test(int i, String...str){
for (String tmp:str){
System.out.println(tmp);
}
System.out.println(i);
}
public static void main(String[] args) {
Main m = new Main();
m.test(3, "Hello", "World");
}
}
可以看到,当调用号test()方法时,str参数可以传入多个字符串作为参数值。从test()方法体代码来看,形参个数可变的参数本质就是一个数组参数,也就是说下面的定义效果相同
//以不定参数来定义方法
public static void test(int i, String...str);
//调用以不定参数形式定义的方法
test(3, "Hello", "World");
//以数组形参来定义方法
public static void test(int i, String[] str);
//调用以不定参数形式定义的方法
test(3, new String[]{"Hello", "World"});
但是要注意,不定形参只能处于形参列表的最后且一个方法最多包含一个不定参数。
下面再看一段代码:
public class Main {
public void test(String str){
System.out.println("只有一个字符串参数");
}
public void test(String...str){
System.out.println("不定参数");
}
public static void main(String[] args) {
Main m = new Main();
m.test();
m.test("Hello", "World");
m.test("HelloWorld");
m.test(new String[]{"Hello"});
}
}
输出:
不定参数
不定参数
只有一个字符串参数
不定参数
因为重载方法的关系,假如只传递一个字符串参数,系统会执行重载的test(String str)方法。若是需要调用test(String...str),又想只传递一个字符串参数,可以用
m.test(new String[]{“Hello”});
三、重写
子类扩展了父类,子类是一个特殊的父类。大部分的时候,子类总是以父类为基础,额外增加新的成员变量和方法。但是有时候,子类需要重写父类的方法。例如鸟类都包含了飞翔方法,其中鸵鸟是一种特殊的鸟类,因此鸵鸟应该是鸟的子类,因此它也将从鸟类获得过飞翔方法,但这个飞翔方法明显不适合鸵鸟。这个时候就需要鸵鸟重写鸟类的方法。
下面看代码:
public class Bird
{
// Bird类的fly()方法
public void fly()
{
System.out.println("我在天空里自由自在地飞翔...");
}
}
public class Ostrich extends Bird
{
// 重写Bird类的fly()方法
public void fly()
{
System.out.println("我只能在地上奔跑...");
}
public void callOverridedMethod()
{
// 在子类方法中通过super来显式调用父类被覆盖的方法。
super.fly();
}
public static void main(String[] args)
{
// 创建Ostrich对象
Ostrich os = new Ostrich();
// 执行Ostrich对象的fly()方法,将输出"我只能在地上奔跑..."
os.fly();
}
}
这种子类包含父类同名方法的现象被称为方法重写。
注意,方法重写要遵循以下准则:
a) 方法名相同、形参列表相同
b) 子类方法返回值类型应比父类方法返回值类型更小或相等
c) 子类方法声明抛出的异常类应比父类抛出的异常类更小或相等
d) 子类方法的访问权限应比父类方法的访问权限更大或相等。
e) 覆盖的方法和被覆盖的要么都是类方法要么都是实例方法,不能一个是类方法一个是实例方法。