Skip to content

Commit 36694ca

Browse files
committed
Update 07-Implementation-Hiding.md
1 parent 0b1bd4f commit 36694ca

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

docs/book/07-Implementation-Hiding.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ import java.util.*
5555

5656
之所以使用导入,是为了提供一种管理命名空间的机制。所有类名之间都是相互隔离的。类 **A** 中的方法 `f()` 不会与类 **B** 中具有相同签名的方法 `f()` 冲突。但是如果类名冲突呢?假设你创建了一个 **Stack** 类,打算安装在一台已经有别人所写的 **Stack** 类的机器上,该怎么办呢?这种类名的潜在冲突,正是我们需要在 Java 中对命名空间进行完全控制的原因。为了解决冲突,我们为每个类创建一个唯一标识符组合。
5757

58-
到目前为止的大部分示例都只存在单个文件,并为本地使用的,所以尚未收到包名的干扰。但是,这些示例其实已经位于包中了,叫做"未命名"包或默认包。这当然是一种选择,为了简单起见,本书其余部分会尽可能采用这种方式。但是,如果你打算为相同机器上的其他 Java 程序创建友好的类库或程序时,就必须仔细考虑以防类名冲突。
58+
到目前为止的大部分示例都只存在单个文件,并为本地使用的,所以尚未受到包名的干扰。但是,这些示例其实已经位于包中了,叫做"未命名"包或默认包。这当然是一种选择,为了简单起见,本书其余部分会尽可能采用这种方式。但是,如果你打算为相同机器上的其他 Java 程序创建友好的类库或程序时,就必须仔细考虑以防类名冲突。
5959

6060
一个 Java 源代码文件称为一个*编译单元*(有时也称*翻译单元*)。每个编译单元的文件名后缀必须是 **.java**。在编译单元中可以有一个 **public** 类,它的类名必须与文件名相同(包括大小写,但不包括后缀名 **.java**)。每个编译单元中只能有一个 **public** 类,否则编译器不接受。如果这个编译单元中还有其他类,那么在包之外是无法访问到这些类的,因为它们不是 **public** 类,此时它们支持主 **public** 类。
6161

@@ -113,7 +113,7 @@ public class ImportedMyClass {
113113

114114
### 创建独一无二的包名
115115

116-
你可能注意到,一个包从未真正被打包成单一的文件,它可以由很多 **.class** 文件构成,因而事情就变得有点复杂了。为了避免这种情况,一种合乎逻辑的做法是将特定包下的所有 **.class** 文件都放在一个目录下。也就是说,利用操作系统的文件结构的层次性。这是 Java 解决解决混乱问题的一种方式;稍后你还会在我们介绍 **jar** 工具时看到另一种方式。
116+
你可能注意到,一个包从未真正被打包成单一的文件,它可以由很多 **.class** 文件构成,因而事情就变得有点复杂了。为了避免这种情况,一种合乎逻辑的做法是将特定包下的所有 **.class** 文件都放在一个目录下。也就是说,利用操作系统的文件结构的层次性。这是 Java 解决混乱问题的一种方式;稍后你还会在我们介绍 **jar** 工具时看到另一种方式。
117117

118118
将所有的文件放在一个子目录还解决了其他的两个问题:创建独一无二的包名和查找可能隐藏于目录结构某处的类。这是通过将 **.class** 文件所在的路径位置编码成 **package** 名称来实现的。按照惯例,**package** 名称是类的创建者的反顺序的 Internet 域名。如果你遵循惯例,因为 Internet 域名是独一无二的,所以你的 **package** 名称也应该是独一无二的,不会发生名称冲突。如果你没有自己的域名,你就得构造一组不大可能与他人重复的组合(比如你的姓名),来创建独一无二的 package 名称。如果你打算发布 Java 程序代码,那么花些力气去获取一个域名是值得的。
119119

@@ -579,7 +579,7 @@ public class OrganizedByAccess {
579579
}
580580
```
581581

582-
这么做只能是程序阅读起来稍微容易一些,因为实现和接口还是混合在一起。也就是说,你仍然能看到源代码——实现部分,因为它就在类中。另外,javadoc 提供的注释文档功能降低了程序代码的可读性对客户端程序员的重要性。将接口展现给类的使用者实际上是类浏览器的任务,类浏览器会展示所有可用的类,并告诉你如何使用它们(比如说那些成员可用)。在 Java 中,JDK 文档起到了类浏览器的作用。
582+
这么做只能是程序阅读起来稍微容易一些,因为实现和接口还是混合在一起。也就是说,你仍然能看到源代码——实现部分,因为它就在类中。另外,javadoc 提供的注释文档功能降低了程序代码的可读性对客户端程序员的重要性。将接口展现给类的使用者实际上是类浏览器的任务,类浏览器会展示所有可用的类,并告诉你如何使用它们(比如说哪些成员可用)。在 Java 中,JDK 文档起到了类浏览器的作用。
583583

584584
<!-- Class Access -->
585585

@@ -662,7 +662,7 @@ public class Lunch {
662662

663663
到目前为止,大部分的方法要么返回 void,要么返回基本类型,所以 [1] 处的定义乍看之下会有点困惑。方法名(**makeSoup**)前面的 **Soup1** 表明了方法返回的类型。到目前为止,这里经常是 **void**,即不返回任何东西。然而也可以返回对象的引用,就像这里一样。这个方法返回了对 **Soup1** 类对象的引用。
664664

665-
**Soup1****Soup2** 展示了如何通过嫁给你所有的构造器声明为 **private** 的方式防止直接创建某个类的对象。记住,如果你不显式地创建构造器,编译器会自动为你创建一个无参构造器(没有参数的构造器)。如果我们编写了无参构造器,那么编译器就不会自动创建构造器了。将构造器声明为 **private**,那么谁也无法创建该类的对象了。但是现在别人该怎么使用这个类呢?上述例子给出了两个选择。在 **Soup1** 中,有一个 **static** 方法,它的作用是创建一个新的 **Soup1** 对象并返回对象的引用。如果想要在返回引用之前在 **Soup1** 上做一些额外操作,或是记录创建了多少个 **Soup1** 对象(可以用来限制数量),这种做法是有用的。
665+
**Soup1****Soup2** 展示了如何通过将你所有的构造器声明为 **private** 的方式防止直接创建某个类的对象。记住,如果你不显式地创建构造器,编译器会自动为你创建一个无参构造器(没有参数的构造器)。如果我们编写了无参构造器,那么编译器就不会自动创建构造器了。将构造器声明为 **private**,那么谁也无法创建该类的对象了。但是现在别人该怎么使用这个类呢?上述例子给出了两个选择。在 **Soup1** 中,有一个 **static** 方法,它的作用是创建一个新的 **Soup1** 对象并返回对象的引用。如果想要在返回引用之前在 **Soup1** 上做一些额外操作,或是记录创建了多少个 **Soup1** 对象(可以用来限制数量),这种做法是有用的。
666666

667667
**Soup2** 用到了所谓的*设计模式*。这种模式叫做*单例模式*,因为它只允许创建类的一个对象。**Soup2** 类的对象是作为 **Soup2** 的 **static** **private** 成员而创建的,所以有且只有一个,你只能通过 **public** 修饰的 `access()` 方法访问到这个对象。
668668

@@ -684,7 +684,7 @@ public class Lunch {
684684

685685
当你具备更改底层实现的能力时,不但可以自由地改善设计,还可能会随意地犯错。无论如何细心地计划和设计,都有可能犯错。当了解到犯错是相对安全的时候,你可以更加放心地实验,更快地学会,更快地完成项目。
686686

687-
类的 **public** 接口是用户真正看到的,所以在分析和设计阶段决定这部分接口是最重要的部分。尽管如此,你仍然有改变的空间。如果最初没有创建出正确的接口,可以添加更多的方法,主要你不删除那些客户端程序员已经在他们的代码中使用的东西
687+
类的 **public** 接口是用户真正看到的,所以在分析和设计阶段决定这部分接口是最重要的部分。尽管如此,你仍然有改变的空间。如果最初没有创建出正确的接口,可以添加更多的方法,只要你不删除那些客户端程序员已经在他们的代码中使用的东西
688688

689689
注意到访问权限控制关注的是类库创建者和外部使用者之间的关系,一种交流方式。很多情况下,事实并非如此。例如,你自己编写了所有的代码,或者在一个小组中工作,所有的东西都放在同一个包下。这些情况下,交流方式则是另外一种,此时严格地遵循访问权限规则也许不是最佳选择,默认(包)访问权限也许就足够好了。
690690

0 commit comments

Comments
 (0)