Skip to content

Commit

Permalink
Update 9.5 违例的限制.md
Browse files Browse the repository at this point in the history
  • Loading branch information
quanke committed May 7, 2016
1 parent 46ec83b commit 2fe3d39
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion 9.5 违例的限制.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# 9.5 违例的限制


9.5 违例的限制
覆盖一个方法时,只能产生已在方法的基础类版本中定义的违例。这是一个重要的限制,因为它意味着与基础类协同工作的代码也会自动应用于从基础类衍生的任何对象(当然,这属于基本的OOP概念),其中包括违例。
下面这个例子演示了强加在违例身上的限制类型(在编译期):

```
//: StormyInning.java
// Overridden methods may throw only the
// exceptions specified in their base-class
Expand Down Expand Up @@ -75,12 +76,18 @@ public class StormyInning extends Inning
} catch(BaseballException e) {}
}
} ///:~
```

在Inning中,可以看到无论构建器还是event()方法都指出自己会“掷”出一个违例,但它们实际上没有那样做。这是合法的,因为它允许我们强迫用户捕获可能在覆盖过的event()版本里添加的任何违例。同样的道理也适用于abstract方法,就象在atBat()里展示的那样。

“interface Storm”非常有趣,因为它包含了在Incoming中定义的一个方法——event(),以及不是在其中定义的一个方法。这两个方法都会“掷”出一个新的违例类型:RainedOut。当执行到“StormyInning extends”和“implements Storm”的时候,可以看到Storm中的event()方法不能改变Inning中的event()的违例接口。同样地,这种设计是十分合理的;否则的话,当我们操作基础类时,便根本无法知道自己捕获的是否正确的东西。当然,假如interface中定义的一个方法不在基础类里,比如rainHard(),它产生违例时就没什么问题。

对违例的限制并不适用于构建器。在StormyInning中,我们可看到一个构建器能够“掷”出它希望的任何东西,无论基础类构建器“掷”出什么。然而,由于必须坚持按某种方式调用基础类构建器(在这里,会自动调用默认构建器),所以衍生类构建器必须在自己的违例规范中声明所有基础类构建器违例。

StormyInning.walk()不会编译的原因是它“掷”出了一个违例,而Inning.walk()却不会“掷”出。若允许这种情况发生,就可让自己的代码调用Inning.walk(),而且它不必控制任何违例。但在以后替换从Inning衍生的一个类的对象时,违例就会“掷”出,造成代码执行的中断。通过强迫衍生类方法遵守基础类方法的违例规范,对象的替换可保持连贯性。

覆盖过的event()方法向我们显示出一个方法的衍生类版本可以不产生任何违例——即便基础类版本要产生违例。同样地,这样做是必要的,因为它不会中断那些已假定基础类版本会产生违例的代码。差不多的道理亦适用于atBat(),它会“掷”出PopFoul——从Foul衍生出来的一个违例,而Foul违例是由atBat()的基础类版本产生的。这样一来,假如有人在自己的代码里操作Inning,同时调用了atBat(),就必须捕获Foul违例。由于PopFoul是从Foul衍生的,所以违例控制器(模块)也会捕获PopFoul。

最后一个有趣的地方在main()内部。在这个地方,假如我们明确操作一个StormyInning对象,编译器就会强迫我们只捕获特定于那个类的违例。但假如我们上溯造型到基础类型,编译器就会强迫我们捕获针对基础类的违例。通过所有这些限制,违例控制代码的“健壮”程度获得了大幅度改善(注释③)。

③:ANSI/ISO C++施加了类似的限制,要求衍生方法违例与基础类方法掷出的违例相同,或者从后者衍生。在这种情况下,C++实际上能够在编译期间检查违例规范。
Expand Down

0 comments on commit 2fe3d39

Please sign in to comment.