两点需要注意:
1 子类的构造函数可以扔出比超类更广泛的异常,但必须包含超类的构造函数扔出的异常
2 子类的方法扔出的异常一定要比超类的“更窄”,这样向上转型时才不会出错
下面是一个例子:
//球类异常基类
class BaseballException extends Exception {}
//犯规
class Foul extends BaseballException {}
//打架
class Strike extends BaseballException {}
//一局球
abstract class Inning {
public Inning() throws BaseballException {}
public void event() throws BaseballException {
//Doesn't actually have to throw anything
}
public void atBat() throws Strike, Foul {
System.out.println("atBat() in superclass Inning");
}
public void walk() {} //Throws no checked exceptions
}
class StormException extends Exception {}
class RainedOut extends StormException {}
class PopFoul extends Foul {}
interface Storm {
public void event() throws RainedOut;
public void rainHard() throws RainedOut;
}
public class StormyInning extends Inning implements Storm {
//构造函数可以扔出新的异常,但必须仍出父类的异常
public StormyInning() throws RainedOut, BaseballException {}
public StormyInning(String s) throws Foul, BaseballException {}
public void walk() {}
public void rainHard() throws RainedOut {}
//下面这样写编译器会报错
//public void event() throws RainedOut {}
//这样写也是错的
//public void event() throws BaseballException {}
//子类可以不扔出异常(比超类更窄),这样向上转型时就不会出错
public void event() {}
//重载的方法可以扔出比超类少的异常或扔出超类异常的子类
public void atBat() throws PopFoul {
System.out.println("atBat() in subclass StormyInning");
}
public static void main(String[] args) {
try {
StormyInning si = new StormyInning();
si.atBat();
} catch(PopFoul e) {
System.out.println("Pop foul");
} catch (RainedOut e) {
System.out.println("Rained out");
} catch (BaseballException e) {
System.out.println("Generic baseball exception");
}
try {
Inning i = new StormyInning();
i.atBat();
} catch(Strike e) {
System.out.println("Strike");
} catch(Foul e) {
System.out.println("Foul");
} catch (RainedOut e) {
System.out.println("Rained out");
} catch (BaseballException e) {
System.out.println("Generic baseball exception");
}
}
}
/*
此程序的输出为:
atBat() in subclass StormyInning
atBat() in subclass StormyInning
即使子类向上转型为超类,然后调用超类的某个方法,其内部也会调用这个子类的方法,这是多态的体现
*/