/*
* 2018年3月28日11:16:43
* 代码目的:
* 核心:
* 当覆盖方法的时候,只能抛出在基类方法的声明里列出的那些异常。这个限制很有用,
* 因为这意味着,当基类使用的代码应用到其派生类对象的时候,一样能够工作
*
*
* 在Inning类中,可以看到构造器和event方法都声明将抛出异常,而实际上并没有抛出异常。
* 这种方式使你能够强制用户去捕获可能在覆盖后的event()版本中增加的异常,所以很合理
Storm接口中event方法不能改变在Inning中event方法的异常接口。
如果接口里定义的方法不是来自于基类,比如rainHard,
那么此方法抛出什么样的异常都没有问题
异常限制对构造器不起作用。但派生类构造器不能捕获基类构造器抛出的异常
StormyInning.walk不能通过编译的目的是因为它抛出了异常,
而Inning.walk并没有声明此异常。
覆盖后的event方法声明,派生类可以不抛出任何异常,
即使它是基类所定义的异常。也可抛出基类方法声明的抛出的异常的派生类也是可以的
*
* */
//: exceptions/StormyInning.java
// Overridden methods may throw only the exceptions
// specified in their base-class versions, or exceptions
// derived from the base-class exceptions.
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 abstract void atBat() throws Strike, Foul;
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 {
// OK to add new exceptions for constructors, but you
// must deal with the base constructor exceptions:
public StormyInning()
throws RainedOut, BaseballException {}
public StormyInning(String s)
throws Foul, BaseballException {}
// Regular methods must conform to base class:
//! void walk() throws PopFoul {} //Compile error
// Interface CANNOT add exceptions to existing
// methods from the base class:
//! public void event() throws RainedOut {}
// If the method doesn't already exist in the
// base class, the exception is OK:
public void rainHard() {}
// You can choose to not throw any exceptions,
// even if the base version does:
public void event() {}
// Overridden methods can throw inherited exceptions:
public void atBat() throws Strike, Foul{}
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");
}
// Strike not thrown in derived version.
try {
// What happens if you upcast?
Inning i = new StormyInning();
i.atBat();
// You must catch the exceptions from the
// base-class version of the method:
} 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");
}
}
} ///:~