java编程思想9.5——异常的限制(继承与实现接口情况下,读书笔记)

来源:互联网 发布:sqlserver数据备份方式 编辑:程序博客网 时间:2024/05/29 21:18
不会经常用到。
9 . 5 违例的限制
覆盖一个方法时,只能产生已在方法的基础类版本中定义的违例。这是一个重要的限制,因为它意味着与基
础类协同工作的代码也会自动应用于从基础类衍生的任何对象(当然,这属于基本的OOP 概念),其中包括
违例。
下面这个例子演示了强加在违例身上的限制类型(在编译期):
//: 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 {
Inning() throws BaseballException {}
void event () throws BaseballException {
// Doesn't actually have to throw anything
}
abstract void atBat() throws Strike, Foul;
void walk() {} // Throws nothing
}
class StormException extends Exception {}
class RainedOut extends StormException {}
class PopFoul extends Foul {}
interface Storm {
void event() throws RainedOut;
void rainHard() throws RainedOut;
}
public class StormyInning extends Inning
implements Storm {
// OK to add new exceptions for constructors,
275
// but you must deal with the base constructor
// exceptions:
StormyInning() throws RainedOut,
BaseballException {}
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() throws RainedOut {}
// You can choose to not throw any exceptions,
// even if base version does:
public void event() {}
// Overridden methods can throw
// inherited exceptions:
void atBat() throws PopFoul {}
public static void main(String[] args) {
try {
StormyInning si = new StormyInning();
si.atBat();
} catch(PopFoul e) {
} catch(RainedOut e) {
} catch(BaseballException e) {}
// 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) {
} catch(Foul e) {
} catch(RainedOut e) {
} catch(BaseballException e) {}
}
} ///:~
在Inning 中,可以看到无论构建器还是event()方法都指出自己会“掷”出一个违例,但它们实际上没有那
样做。这是合法的,因为它允许我们强迫用户捕获可能在覆盖过的event()版本里添加的任何违例。同样的
道理也适用于abstract 方法,就象在atBat()里展示的那样。
“interface Storm”非常有趣,因为它包含了在Incoming 中定义的一个方法——event(),以及不是在其中
定义的一个方法。这两个方法都会“掷”出一个新的违例类型:RainedOut。当执行到“StormyInning
extends”和“implements Storm”的时候,可以看到Storm 中的event()方法不能改变Inning中的event()
的违例接口。同样地,这种设计是十分合理的;否则的话,当我们操作基础类时,便根本无法知道自己捕获
的是否正确的东西。当然,假如interface 中定义的一个方法不在基础类里,比如rainHard(),它产生违例
时就没什么问题。
对违例的限制并不适用于构建器。在StormyInning 中,我们可看到一个构建器能够“掷”出它希望的任何东
西,无论基础类构建器“掷”出什么。然而,由于必须坚持按某种方式调用基础类构建器(在这里,会自动
276
调用默认构建器),所以衍生类构建器必须在自己的违例规范中声明所有基础类构建器违例。
StormyInning.walk()不会编译的原因是它“掷”出了一个违例,而Inning.walk() 却不会“掷”出。若允许
这种情况发生,就可让自己的代码调用Inning.walk(),而且它不必控制任何违例。但在以后替换从Inning
衍生的一个类的对象时,违例就会“掷”出,造成代码执行的中断。通过强迫衍生类方法遵守基础类方法的
违例规范,对象的替换可保持连贯性。
覆盖过的event()方法向我们显示出一个方法的衍生类版本可以不产生任何违例——即便基础类版本要产生
违例。同样地,这样做是必要的,因为它不会中断那些已假定基础类版本会产生违例的代码。差不多的道理
亦适用于atBat(),它会“掷”出PopFoul——从Foul 衍生出来的一个违例,而Foul 违例是由atBat()的基
础类版本产生的。这样一来,假如有人在自己的代码里操作Inning,同时调用了atBat(),就必须捕获Foul
违例。由于PopFoul 是从Foul 衍生的,所以违例控制器(模块)也会捕获PopFoul。
最后一个有趣的地方在main()内部。在这个地方,假如我们明确操作一个StormyInning 对象,编译器就会
强迫我们
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 甘肃 旅游 甘肃景区 甘肃简介 甘肃自驾游 甘肃周边游 甘肃青海 甘肃科技 甘肃麦积山 甘肃静宁 甘肃联通 青海甘肃 甘肃学校 甘肃月牙泉 成都到甘肃 甘肃交通 甘肃靖远 甘肃庄浪 甘肃通渭 甘肃崇信 甘肃临泽 甘肃夏河 甘肃到新疆 甘肃武山 甘肃采购网 甘肃 嘉峪关 甘肃秦安 甘肃永登 甘肃永靖 甘肃景泰 甘肃中专 甘肃正宁 甘肃高台 甘肃周边 甘肃旅游网 甘肃万维 甘肃张家川 甘肃电力 甘肃民乐 甘肃土豆 甘肃 敦煌 甘肃人事网