重载(Overload):方法名称相同,但形参列表不同,则被称为方法重载
规则:两同一不同(同一类中方法名相同,参数列表不同),注意点:方法返回值类型、修饰符与重载没有关系
构造器也是可以重载的,如果构造器的修饰符可以是protected,这样保证了只有同类或子类可以new该实例对象,如
protected Test(){...};
重写(也叫覆盖Override):重写父类的方法
规则:两同两小一大(同方法名,同参数列表;返回值类型需要是父类该方法的返回值类型或者是其子类型,抛出异常类型应该是父类该方法抛出异常类型或者是其子类型;其方法的访问权限应该比父类该方法相等或大)
练习题
下面题目可以考查对于重写的理解
public class Parent { public void a(){} private void b(){} public Parent c(){return null;} public Son d(){return null;} public String e(){return " ";} public float f(){return 0;} } class Son extends Parent { //这里可以填充的代码 }
下面哪些代码能填充到
(1)private void a() { } 不可以(访问权限比父类方法权限小)
(2)private void b() { } 可以(但是该方法不是方法覆盖,是子类的私有方法)
(3)public void b() { } 可以(但是该方法不是方法覆盖,是子类的私有方法)
(4)public Son c() { return null; } 可以
(5)public Parent d() { return null;} 不可以
(6)public Son a() { return null;} 不可以
(7)public long a() { return 0;} 不可以
(8)public char e() { return 0;} 不可以
(9)public double f() { return 0;} 不可以
含有抛出异常方法重写的疑惑
下面是对重写过程中有抛出异常的情况,有几点疑惑:
java中的重写过程如果出现有抛出异常的方法,我看书和网上都是这样的意思:子类方法只能抛出比父类被重写的方法抛出更小的异常,也即是只能是父类抛出的异常或子异常。但是我自己测试的结果让我很不解,下面是我几点疑惑的地方:
1、为何代码一能通过,但是代码二不能通过编译,Exception是RuntimeException的父类,父类方法没有抛出异常,子类覆盖该方法,能抛出哪些异常?
代码一:
public class Parent { public void a() {} } class Son extends Parent { public void a() throws RuntimeException{} }
代码二:
public class Parent { public void a() {} } class Son extends Parent { public void a() throws Exception {} }
2、下面代码一和代码二怎么可以编译通过,IOException和RuntimeException及其子类NullPointerException并没有继承关系,但是如果代码抛出异常交换则不能通过编译,如代码三和代码四
代码一:
public class Parent { public void a() throws IOException {} } class Son extends Parent { public void a() throws RuntimeException{} }
代码二:
public class Parent { public void a() throws IOException {} } class Son extends Parent { public void a() throws NullPointerException{} }
代码三:
public class Parent { public void a() throws RuntimeException {} } class Son extends Parent { public void a() throws IOException{} }
代码四:
public class Parent { public void a() throws NullPointerException {} } class Son extends Parent { public void a() throws IOException{} }
3、如果我抛出的是错误,是否在重写的时候就没有什么规则了,因为下面代码我测试是通过的,我的理解是Error是不能抛出的,是系统内部处理的?我这样理解有问题吗?
public class Parent { public void a() throws IOError{} } class Son extends Parent { public void a() throws Error{} }
对于有抛出异常的方法重写,应该这样理解:
More precisely, suppose that B is a class or interface, and A is a superclass or superinterface of B, and a method declaration n
in B overrides
or hides a method declaration m
in A. Then:
-
If
n
has athrows
clause that mentions any checked exception types, thenm
must have athrows
clause,
or a compile-time error occurs. -
For every checked exception type listed in the
throws
clause ofn
, that same exception class or one of its supertypes must
occur in the erasure (§4.6) of thethrows
clause ofm
; otherwise, a compile-time
error occurs. -
If the unerased
throws
clause ofm
does not contain a supertype of each exception type in thethrows
clause ofn
,
a compile-time unchecked warning occurs.
异常继承体系结构图: