重写和重载是一对比较容易混淆的概念
从参数列表来说:重写的各个方法参数列表必须相同,重载的各个方法参数列表必须不同(但是函数名字相同)
从返回值来说:重写的各个方法返回值类型必须相同,重载的各个方法返回值可以不同也可以相同
异常:重写的方法可以消除原有的异常,但是不可以抛出新的异常,重写是对异常没有限制
可见性:重写的方法可见性可以与原来持平或者在原有基础上增加,但是不能降低,重写对可见性没有限制
调用选择:
重写的方法,根据实际的对象类型(而不是声明的)来决定调用哪个方法,但是注意,在此之前还有静态检查,也就是说,重写的方法至少要在定义的类型中有声明,如:
class Animal{ public void eat(); } class Cow implements Animal { public void moo() { System.out.println("Moo!");} } Animal a = new Cow(); a.moo(); //Compile error: undefined method moo()
根据实际类型来看,a是Cow类型的对象,是存在moo方法的,但是在静态检查中,a会以Animal类型进行静态检查。而在Animal类型中并不存在moo方法,所以无法通过编译。
其实重写是多态的一种体现。但是能体现多态,首先声明的类型中应该有这个状态。
这个例子中我们也能发现,重写的方法选择其实是在运行时进行的。
重载的方法函数名相同但参数类型不同,所以是通过参数类型来进行选择的,本质上是静态类型的选择,声明都不同。所以重载的方法选择是在编译时进行的。
示例:
public class temp { public int f() { return 0; } public int f(int a) { return 1; } public int f(char b) { return 2; } public int f2() { return 0; } }
public class temp2 extends temp{ @Override public int f2() { return 1; } }
temp类中的三个f方法的声明就是重载
temp2类中的f2方法对temp类中的f2方法进行了重写
文章评论