重载overload和重写override的区别
public class MethodOverrideVSOverload { //因为参数与Object的equals方法不同,故没有重写equals方法,而是重载关系 public boolean equals(MethodOverrideVSOverload other) { System.out.println("MethodOverrideVSOverload"); return true; } /** * @param args */ public static void main(String[] args) { //编译期o1和o2都是Object对象,故调用的还是Object的equals方法 Object o1=new MethodOverrideVSOverload(); Object o2=new MethodOverrideVSOverload(); //编译期o3,o4是MethodOverrideVSOverload,故调用的是MethodOverrideVSOverload //的equals方法,重载发生在编译期,重写发生在运行期。 MethodOverrideVSOverload o3=new MethodOverrideVSOverload(); MethodOverrideVSOverload o4=new MethodOverrideVSOverload(); if(o1.equals(o2)) { System.out.println("Object o1 and o2 is equal."); } if(o3.equals(o4)) { System.out.println("Object o3 and o4 is equal."); } } }
结果输出是:
MethodOverrideVSOverload
Object o3 and o4 is equal.
为什么会这样呢?
首先要搞清楚重载和重写的关系。
重载指的是同一个类中,方法名相同但形参列表不同,重载是编译时静态绑定的。
重写则是指,子类覆盖父类的同名方法,重写是运行时动态绑定的。
对于子类重写的要求如下:
参数列表,返回值(可以是子类)均不可变。
可以抛出更少的异常,但不可抛出父类未声明的异常。
访问权限比起父类要更宽松。
运行时根据对象类型来决定调用的方法。
看回程序,public boolean equals()方法看起来是跟Object的equals方法有点像,实际上形参不一样,所以这里应该是方法重载而不是重写。
o1,o2实际上是调用了Object的equals方法,因为他们的编译时类型是Object,而o3,o4则是调用MethodOverrideVsOverload的方法。
怎样解决这个问题呢?
使用一个Annotation来进行说明,@Override,当用了这个Annotation时,因为形参列表不一样,则会报错。
@Override public boolean equals(Object other) { System.out.println("MethodOverrideVSOverload"); return true; }
这时候的结果是:
MethodOverrideVSOverload
Object o1 and o2 is equal.
MethodOverrideVSOverload
Object o3 and o4 is equal.