重写(Override)的目的
老子和小子之间有代沟,老子喜欢成熟稳重的,而小子喜欢漂亮的。为了解决这个代沟问题,重写赋予了子类能够按照自己的方式选择的能力。当然,子类也可以按照父类的方式处理,毕竟是儿子,调用super.xxx()就可以。重写的在模板方法中用的比较多,父类定义了一定的流程,要做哪些事情,具体怎么做交给子类去实现。
重写和重载(Overload)的区别
- 重载(Overload)指的是相同的方法名,不同的参数(类型或个数)。重载是一种编译时行为,在编译完成后调用哪个方法就已经固定了。
- 重写体现在运行中,由对象的类型决定调用哪一个方法。(使用父类的引用指向子类)
重写的规则(属性也是可以被重写的)
- 参数列表必须完全与被重写方法的相同;
- 返回类型必须完全与被重写方法的返回类型相同;
- 父类的方法必须能被继承,子类的访问权限必须大于父类中被重写的方法的访问权限(否则就是语法错误)。
- 父类的方法不能为final,final是不允许被重写。
- 父类的方法不能为static的方法,static表示类的一种修饰,而不是对象。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常(非强制异常米有关系只要不触及底线,爱咋玩咋玩)。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。(异常比较家当,老子的当家就只有这么多,不能超了)
代码示例
用一个Object.equals(Object o)来做为例子,来显示去重写和重载的区别,当然这个问题我曾经也犯过错。就是因为参数不同,本意为重写的,变成了重载。
public class Test{
public static void main(String[] args) {
Tester test = new Tester();
Object obj = test;
test.equals(test);
test.equals(obj);
}
private static class Tester {
@Override
public boolean equals(Object o) {
System.out.println("override");
return false;
}
public boolean equals(Tester tt) {
System.out.println("overload");
return false;
}
}
}
在集合类中,比如List的remove(Object o)
方法形参也是Object,这里也没有使用泛型(如果使用泛型,感觉会更加直观)。以ArrayList为例,使用数组来保存数据,数组还没有泛型数组,如果用泛型也还是和Object类型的做对比,而equals方法是重写,用对象类型决定,所以形参是Object,只要是泛型E对应的类型,也是没有问题的。