重载方法必须满足下列条件
(1) 方法名必须相同
(2) 方法的参数签名必须相同
(3) 方法的返回类型和方法的修饰符可以不相同
方法覆盖必须满足下列条件
(1) 子类的方法的名称及参数必须和所覆盖的方法相同
(2) 子类的方法返回类型必须和所覆盖的方法相同
(3) 子类方法不能缩小所覆盖方法的访问权限
(4) 子类方法不能抛出比所覆盖方法更多的异常
下面是一些例子:引自http://blog.csdn.net/bnuchampion/archive/2008/01/07/2028119.aspx
Base------------------------------------------
package chapter6;
public class Base {
public int publicVarOfBase = 1;
protected int protectedVarOfBase = 1;
int defaultVarOfBase = 1;
// private int privateVarOfBase = 1;
public void publicMethodOfBase() {
System.out.println("publicMethodOfBase()");
}
protected void protectedMethodOfBase() {
System.out.println("protectedMethodOfBase()");
}
void defaultMethodOfBase() {
System.out.println("defaultMethodOfBase()");
}
/*
* private void privateMethodOfBase() { privateVarOfBase = 2;
* System.out.println("privateMethodOfBase()"); }
*/
}
Sub------------------------------------------
package chapter6;
public class Sub extends Base {
public static void main(String[] args) {
Sub sub = new Sub();
System.out.println(sub.publicVarOfBase);
System.out.println(sub.protectedVarOfBase);
System.out.println(sub.defaultVarOfBase);
sub.publicMethodOfBase();
sub.protectedMethodOfBase();
sub.defaultMethodOfBase();
}
}
-------------------------------------------------
对于方法重载来说,关键就是参数的类型、参数的个数、参数的顺序至少有一项不相同。至于修饰符(private/protected/public/abstract/final/static),返回类型都无所谓。
------------------------------------------------
怎样才算是一个方法覆盖:
1 首先要保证方法名、参数类型、参数个数、参数顺序完全一样
2 返回类型也必须要一致
3 子类方法不能缩小父类方法的访问权限比如不能由public变成private了如果可以的话请看下面一段代码会出现什么问题
package chapter6;
class Base {
public void method() {
System.out.println("Base");
}
}
public class Sub extends Base {
private void method() {
System.out.println("Sub");
}
public static void main(String[] args) {
Base sub = new Sub();
sub.method();
}
}
4 子类方法不能抛出比父类方法更多的异常,只能够相同,或者是父类方法抛出的异常类的子类。
因为如果可以的话,就会与Java语言的多态机制发生冲突,比如:
package chapter6;
import java.io.IOException;
class Base {
protected void method() throws ExceptionSub1 {
System.out.println("Base");
throw new ExceptionSub1();
}
}
public class Sub extends Base {
public void method() throws ExceptionBase {
System.out.println("Sub");
throw new ExceptionBase();
}
public static void main(String[] args) {
Base sub = new Sub();
try {
sub.method();
} catch (ExceptionSub1 ex) {
System.out.println("ok!");
}
}
}
不过这句话也不全对看下面一个实例:
package chapter6;
class Base {
protected void method() throws IndexOutOfBoundsException {
System.out.println("Base");
}
}
public class Sub extends Base {
public void method() throws RuntimeException {
System.out.println("Sub");
}
public static void main(String[] args) {
Base sub = new Sub();
try {
sub.method();
} catch (Exception ex) {
}
}
}
可是IndexOutOfBoundsException却是RuntimeException的子类!要抛出的是java.lang.RuntimeException就无所谓了,因为运行时异常可以不用做检查。
5 父类的static方法不能被子类覆盖为非static方法 子类可以定义static方法覆盖父类的static方法 子类不可以定义static方法覆盖父类的非static方法
6 子类方法覆盖父类方法的前提是,子类必须能够继承父类的特定方法
class Base {
private void method() throws ExceptionBase {
System.out.println("Base");
}
}
public class Sub extends Base {
public void method() throws ExceptionSub1 {
System.out.println("Sub");
}
public static void main(String[] args) {
Sub sub = new Sub();
try {
sub.method();
} catch (ExceptionBase ex) {
ex.printStackTrace();
}
}
}
因此Base的method()方法和Sub的method()方法没有覆盖关系!再看
class Base {
private String showMe(){
return "Base";
}
public void print(){
System.out.println(showMe());
}
}
public class Sub extends Base {
public String showMe(){
return "Sub";
}
public static void main(String[] args) {
Sub sub = new Sub();
sub.print();
}
}
执行的结果将是"Base" 这是因为print()方法在Base类中定义,因此print()方法会调用在Base类中定义的private类型的showMe()方法。如果把private改为其它,将会打印"Sub",因为这个时候有方法覆盖!
7 父类的抽象方法可以被子类通过两种途径覆盖:一是子类实现父类的抽象方法;二是子类重新声明父类的抽象方法。
abstract class Base {
abstract void method1();
abstract void method2();
}
public abstract class Sub extends Base {
void method1() {
}
abstract void method2();
}
父类的非抽象方法可以被覆盖为抽象方法!
abstract class Base {
void method1(){System.out.println("method1");};
abstract void method2();
}
public abstract class Sub extends Base {
abstract void method1();
void method2(){System.out.println("method2");};
public static void main(String[] args) {
Sub sub = new End();
sub.method1();
}
}
class End extends Sub {
void method1(){
System.out.println("end-method1");
}
}
结果将为"end-method1"