File tree Expand file tree Collapse file tree 2 files changed +4
-2
lines changed Expand file tree Collapse file tree 2 files changed +4
-2
lines changed Original file line number Diff line number Diff line change @@ -1176,12 +1176,14 @@ public class Jurassic {
1176
1176
1177
1177
但请留意你的假设。通常来说,预见一个类如何被复用是很困难的,特别是通用类。如果将一个方法指定为 ** final** ,可能会防止其他程序员的项目中通过继承来复用你的类,而这仅仅是因为你没有想到它被以那种方式使用。
1178
1178
1179
- Java 标准类库就是一个很好的例子。尤其是 Java 1.0/1.1 的 ** Vector** 类被广泛地使用,如果它的所有方法没有因为从效率考虑(这近乎是个幻想),而被指定为 ** final** ,可能会更加有用。很容易想到,你可能会继承并覆写这么一个基础类,但是设计者们认为这么做不合适。有两个讽刺的原因。第一,** Stack** 继承自 ** Vector** ,就是说 ** Stack** 是个 ** Vector** ,但从逻辑上来说不对。尽管如此,Java 设计者们仍然这么做,在用这种方式创建 ** Stack** 时,他们应该意识到了 ** final** 方法过于约束。
1179
+ Java 标准类库就是一个很好的例子。尤其是 Java 1.0/1.1 的 ** Vector** 类被广泛地使用,然而它的所有方法出于"效率"考虑(然而并没有提升效率,只是幻觉)全被指定为 ** final ** ,如果不指定 ** final** 的话 ,可能会更加有用[ ^ 1 ] 。很容易想到,你可能会继承并覆写这么一个基础类,但是设计者们认为这么做不合适。有两个讽刺的原因。第一,** Stack** 继承自 ** Vector** ,就是说 ** Stack** 是个 ** Vector** ,但从逻辑上来说不对。尽管如此,Java 设计者们仍然这么做,在用这种方式创建 ** Stack** 时,他们应该意识到了 ** final** 方法过于约束。
1180
1180
1181
1181
第二,** Vector** 中的很多重要方法,比如 ` addElement() ` 和 ` elementAt() ` 方法都是同步的。在“并发编程”一章中会看到同步会导致很大的执行开销,可能会抹煞 ** final** 带来的好处。这加强了程序员永远无法正确猜到优化应该发生在何处的观点。如此笨拙的设计却出现在每个人都要使用的标准库中,太糟糕了。庆幸的是,现代 Java 容器用 ** ArrayList** 代替了 ** Vector** ,它的行为要合理得多。不幸的是,仍然有很多新代码使用旧的集合类库,其中就包括 ** Vector** 。
1182
1182
1183
1183
Java 1.0/1.1 标准类库中另一个重要的类是 ** Hashtable** (后来被 ** HashMap** 取代),它不含任何 ** final** 方法。本书中其他地方也提到,很明显不同的类是由不同的人设计的。** Hashtable** 就比 ** Vector** 中的方法名简洁得多,这又是一条证据。对于类库的使用者来说,这是一个本不应该如此草率的事情。这种不规则的情况造成用户需要做更多的工作——这是对粗糙的设计和代码的又一讽刺。
1184
1184
1185
+ - ** [ 1] ** Java 1.4 开始已将 ** Vector** 类大多数方法的 ** final** 去掉
1186
+
1185
1187
<!-- Initialization and Class Loading -->
1186
1188
1187
1189
## 类初始化和加载
Original file line number Diff line number Diff line change @@ -104,7 +104,7 @@ public class Instantiable extends Uninstantiable {
104
104
}
105
105
```
106
106
107
- 留意 ` @Override ` 的使用。没有这个注解的话,如果你没有定义相同的方法名或签名,抽象机制会认为你没有实现抽象方法从而产生编译时错误。因此,你可能认为这里的 ` @Override ` 是多余的。但是,` @Override ` 还提示了这个方法被覆写——我认为这是有用的,所以我会使用 ` @Override ` ,即使在没有这个注解,编译器告诉我错误的时候 。
107
+ 留意 ` @Override ` 的使用。没有这个注解的话,如果你没有定义相同的方法名或签名,抽象机制会认为你没有实现抽象方法从而产生编译时错误。因此,你可能认为这里的 ` @Override ` 是多余的。但是,` @Override ` 还提示了这个方法被覆写——我认为这是有用的,所以我会使用 ` @Override ` ,不仅仅是因为当没有这个注解时,编译器会告诉我出错 。
108
108
109
109
记住,事实上的访问权限是“friendly”。你很快会看到接口自动将其方法指明为 ** public** 。事实上,接口只允许 ** public** 方法,如果不加访问修饰符的话,接口的方法不是 ** friendly** 而是 ** public** 。然而,抽象类允许每件事:
110
110
You can’t perform that action at this time.
0 commit comments