File tree 2 files changed +6
-6
lines changed
2 files changed +6
-6
lines changed Original file line number Diff line number Diff line change @@ -964,7 +964,7 @@ Disposing Shared 0
964
964
965
965
** static long counter** 跟踪所创建的 ** Shared** 实例数量,还提供了 ** id** 的值。** counter** 的类型是 ** long** 而不是 ** int** ,以防溢出(这只是个良好实践,对于本书的所有示例,** counter** 不会溢出)。** id** 是 ** final** 的,因为它的值在初始化时确定后不应该变化。
966
966
967
- 在将一个 ** shared** 对象附着在类上时,必须记住调用 ` addRef() ` ,而 ` dispose() ` 方法会跟踪引用数,以确定在何时真正地执行清理工作。使用这种技巧需要加倍细心,但是如果正在共享需要被清理的对象,就没有太多选择了 。
967
+ 在将一个 ** shared** 对象附着在类上时,必须记住调用 ` addRef() ` ,而 ` dispose() ` 方法会跟踪引用数,以确定在何时真正地执行清理工作。使用这种技巧需要加倍细心,但是如果需要清理正在共享的对象,你没有太多选择 。
968
968
969
969
### 构造器内部多态方法的行为
970
970
@@ -1154,7 +1154,7 @@ HappyActor
1154
1154
SadActor
1155
1155
```
1156
1156
1157
- ** Stage** 对象中包含了 ** Actor** 引用,该引用被初始化为指向一个 ** HappyActor** 对象,这意味着 ` performPlay() ` 会产生一个特殊行为。但是既然引用可以在运行时与其他不同的对象绑定,那么它就可以被替换成对 ** SadActor** 的引用,` performPlay() ` 的行为随之改变。这样你就获得了运行时的动态灵活性(这被称为状态模式)。与之相反,我们不能在运行时决定继承不同的对象,那在编译时就完全确定下来了 。
1157
+ ** Stage** 对象中包含了 ** Actor** 引用,该引用被初始化为指向一个 ** HappyActor** 对象,这意味着 ` performPlay() ` 会产生一个特殊行为。但是既然引用可以在运行时与其他不同的对象绑定,那么它就可以被替换成对 ** SadActor** 的引用,` performPlay() ` 的行为随之改变。这样你就获得了运行时的动态灵活性(这被称为状态模式)。与之相反,我们无法在运行时才决定继承不同的对象;那在编译时就完全决定好了 。
1158
1158
1159
1159
有一条通用准则:使用继承表达行为的差异,使用属性表达状态的变化。在上个例子中,两者都用到了。通过继承得到的两个不同类在 ` act() ` 方法中表达了不同的行为,** Stage** 通过组合使自己的状态发生变化。这里状态的改变产生了行为的改变。
1160
1160
Original file line number Diff line number Diff line change @@ -602,7 +602,7 @@ public interface Operations {
602
602
}
603
603
```
604
604
605
- 这是模版方法设计模式的一个版本 (在“设计模式”一章中详细描述),` runOps() ` 是一个模版方法。` runOps() ` 使用可变参数列表,因而我们可以传入任意多的 ** Operation** 参数并按顺序运行它们:
605
+ 这是 * 模版 * 方法设计模式的一个版本 (在“设计模式”一章中详细描述),` runOps() ` 是一个模版方法。` runOps() ` 使用可变参数列表,因而我们可以传入任意多的 ** Operation** 参数并按顺序运行它们:
606
606
607
607
``` java
608
608
// interface/Machine.java
@@ -768,17 +768,17 @@ Woodwind.play() MIDDLE_C
768
768
| 状态 | 不能包含属性(除了静态属性,不支持对象状态) | 可以包含属性,非抽象方法可能引用这些属性 |
769
769
| 默认方法 和 抽象方法 | 不需要在子类中实现默认方法。默认方法可以引用其他接口的方法 | 必须在子类中实现抽象方法 |
770
770
| 构造器 | 没有构造器 | 可以有构造器 |
771
- | 可见性 | 隐式 ** public** | 可以是 ** protected** 或友元 |
771
+ | 可见性 | 隐式 ** public** | 可以是 ** protected** 或 "friendly" |
772
772
773
773
抽象类仍然是一个类,在创建新类时只能继承它一个。而创建类的过程中可以实现多个接口。
774
774
775
- 有一条实际经验:尽可能地抽象 。因此,更倾向使用接口而不是抽象类。只有当必要时才使用抽象类。除非必须使用,否则不要用接口和抽象类。大多数时候,普通类已经做得很好,如果不行的话,再移动到接口或抽象类中。
775
+ 有一条实际经验:在合理的范围内尽可能地抽象 。因此,更倾向使用接口而不是抽象类。只有当必要时才使用抽象类。除非必须使用,否则不要用接口和抽象类。大多数时候,普通类已经做得很好,如果不行的话,再移动到接口或抽象类中。
776
776
777
777
<!-- Complete Decoupling -->
778
778
779
779
## 完全解耦
780
780
781
- 当方法操纵的是一个类而非接口时,它就只能作用于那个类或其子类。如果想把方法应用于那个继承层级结构之外的类,就会触霉头 。接口在很大程度上放宽了这个限制,因而使用接口可以编写复用性更好的代码。
781
+ 每当一个方法与一个类而不是接口一起工作时(当方法的参数是类而不是接口),你只能应用那个类或它的子类。如果你想把这方法应用到一个继承层次之外的类,是做不到的 。接口在很大程度上放宽了这个限制,因而使用接口可以编写复用性更好的代码。
782
782
783
783
例如有一个类 ** Processor** 有两个方法 ` name() ` 和 ` process() ` 。` process() ` 方法接受输入,修改并输出。把这个类作为基类用来创建各种不同类型的 ** Processor** 。下例中,** Processor** 的各个子类修改 String 对象(注意,返回类型可能是协变类型而非参数类型):
784
784
You can’t perform that action at this time.
0 commit comments