Java编程思想外文翻译资料

 2023-03-15 04:03

Java编程思想

第6章 权限访问控制

访问控制(或隐藏具体实现)与“最初的实现并不恰当”有关。

所有优秀的作者,包括那些编写软件的程序员,都清楚其著作的某些部分直至重新创作的时候才变得完美,有时甚至要反复重写多次。如果你把一个代码段放到了某个位置,等过一会儿回头再看时,有可能会发现有更好的方式去实现相同的功能。这正是重构的原动力之一,重构即重写代码,以使得它更可读、更易理解,并因此而更具可维护性。

但是,在这种修改和完善代码的愿望之下,也存在着巨大的压力。通常总是会有一些消费者(客户端程序员)需要你的代码在某些方面保持不变。因此你想改变代码,而他们却想让代码保持不变。由此而产生了在面向对象设计中需要考虑的一个基本问题:“如何把变动的事物与保持不变的事物区分开来”。

这对类库(library)而言尤为重要。该类库的消费者必须依赖他所使用的那部分类库,并且能够知道如果类库出现了新版本,他们并不需要改写代码。从另一个方面来说,类库的开发者必须有权限进行修改和改进,并确保客户代码不会因为这些改动而受到影响。

这一目标可以通过约定来达到。例如,类库开发者必须同意在改动类库中的类时不得删除任何现有方法,因为那样会破坏客户端程序员的代码。但是,与之相反的情况会更加棘手。在有域(即数据成员)存在的情况下,类库开发者要怎样才能知道究竞都有哪些域已经被客户端程序员所调用了呢?这对于方法仅为类的实现的一部分,因此并不想让客户端程序员直接使用的情况来说同样如此。如果程序开发者想要移除旧的实现而要添加新的实现时,结果将会怎样呢?改动任何一个成员都有可能破坏客户端程序员的代码。于是类库开发者会手脚被缚,无法对任何事物进行改动。

为了解决这一问题,Java提供了访问权限修饰词,以供类库开发人员向客户端程序员指明哪些是可用的,哪些是不可用的。访问权限控制的等级,从最大权限到最小权限依次为: public、protected、包访问权限(没有关键词)和private。根据前述内容,读者可能会认为,作为一名类库设计员,你会尽可能将一切方法都定为private,而仅向客户端程序员公开你愿意让他们使用的方法。这样做是完全正确的,尽管对于那些经常使用别的语言(特别是C语言)编写程序并在访问事物时不受任何限制的人而言,这与他们的直觉相违背。到了本章末,读者将会信服Java的访问权限控制的价值。

不过,构件类库的概念以及对于谁有权取用该类库构件的控制问题都还是不完善的。其中仍旧存在着如何将构件捆绑到一个内聚的类库单元中的问题。对于这一点,Java用关键字package加以控制,而访问权限修饰词会因类是存在于一个相同的包,还是存在于一个单独的包而受到影响。为此,要开始学习本章,首先要学习如何将类库构件置于包中,然后就会理解访问权限修饰词的全部含义。

6.1 包:库单元

包内包含有一组类,它们在单一的名字空间之下被组织在了一起。

例如,在Java的标准发布中有一个工具库,它被组织在java.util名字空间下。Java.util中有一个叫做ArrayList的类,使用ArrayList的一种方式是用其全名java.util.ArrayList来指定。

这立刻使程序变得很冗长了,因此你可能想转而使用import关键字。如果你想要导入单个的类,可以在import语句中命名该类:

现在,就可以不用限定地使用ArrayList了。但是,这样做java.util中的其他类仍旧是不可用的。要想导入其中所有的类,只需要使用“*”,就像在书本剩余部分的示例中看到的那样:

import java.util.*;

我们之所以要导入,就是要提供一个管理名字空间的机制。所有类成员的名称都是彼此隔离的。A类中的方法f( )与B类中具有相同特征标记(参数列表)的方法f( )不会彼此冲突。但是如果类名称相互冲突又该怎么办呢?假设你编写了一个Stack类并安装到了一台机器上,而该机器上已经有了一个别人编写的Stack类,我们该如何解决呢?由于名字之间的潜在冲突,在Java中对名称空间进行完全控制并为每个类创建唯一的标识符组合就成为了非常重要的事情。

到目前为止,书中大多数示例都存于单一文件之中,并专为本地使用(local use)而设计,因而尚未受到包名的干扰。这些示例实际上已经位于包中了:即未命名包,或称为默认包。这当然也是一种选择,而且为了简单起见,在本书其他部分都尽可能地使用了此方法。不过如果你正在准备编写对在同一台机器上共存的其他Java程序友好的类库或程序的话,就需要考虑如何防止类名称之间的冲突问题。

当编写一个Java源代码文件时,此文件通常被称为编译单元(有时也被称为转译单元)。每个编译单元都必须有一个后缀名.java,而在编译单元内则可以有一个public类,该类的名称必须与文件的名称相同(包括大小写,但不包括文件的后缀名.java)。每个编译单元只能有一个public类,否则编译器就不会接受。如果在该编译单元之中还有额外的类的话,那么在包之外的世界是无法看见这些类的,这是因为它们不是public类,而且它们主要用来为主public类提供支持。

6.1.1 代码组织

当编译一个.java文件时,在.java文件中的每个类都会有一个输出文件,而该输出文件的名称与.java文件中每个类的名称相同,只是多了一个后缀名.class。因此,在编译少量.java文件之后,会得到大量的.class文件。如果用编译型语言编写过程序,那么对于编译器产生一个中间文件(通常是一个obj文件),然后再与通过链接器(用以创建一个可执行文件)或类库产生器(librarian,用以创建一个类库)产生的其他同类文件捆绑在一起的情况,可能早已司空见惯。但这并不是Java的工作方式。Java可运行程序是一组可以打包并压缩为一个Java文档文件(JAR,使用Java的jar文档生成器)的.class文件。Java解释器负责这些文件的查找、装载和解释。

类库实际上是一组类文件。其中每个文件都有一个public类,以及任意数量的非public类。因此每个文件都有一个构件。如果希望这些构件(每一个都有它们自己的独立的.java和.class文件)从属于同一个群组,就可以使用关键字package。

如果使用package语句,它必须是文件中除注释以外的第一句程序代码。在文件起始处写:

package access;

就表示你在声明该编译单元是名为access的类库的一部分。或者换种说法,你正在声明该编译单元中的public类名称是位于access名称的保护伞下。任何想要使用该名称的人都必须使用前面给出的选择,指定全名或者与access结合使用关键字import。(请注意,Java 包的命名规则全部使用小写字母,包括中间的字也是如此。)

例如,假设文件的名称是MyClass.java,这就意味着在该文件中有且只有一个public类,该类的名称必须是MyClass(注意大小写):

现在,如果有人想用MyClass或者是access中的任何其他public类,就必须使用关键字import来使access中的名称可用。另一个选择是给出完整的名称:

关键字import可使之更加简洁:

身为一名类库设计员,很有必要牢记:package和import关键字允许你做的,是将单一的全局名字空间割开,使得无论多少人使用Internet及Java开始编写类,都不会出现名称冲突问题。

6.1.2 创建独一无二的包名

读者也许会发现,既然一个包从未真正将被打包的东西包装成单一的文件,并且一个包可以由许多.class文件构成,那么情况就有点复杂了。为了避免这种情况的发生,一种合乎逻辑的做法就是将特定包的所有.class文件都置于一个目录下。也就是说,利用操作系统的层次化的文件结构来解决这一问题。这是Java解决混乱问题的一种方式,读者还会在我们介绍jar工具的时候看到另一种方式。

将所有的文件收入一个子目录还可以解决另外两个问题:怎样创建独一无二的名称以及怎样查找有可能隐藏于目录结构中某处的类。这些任务是通过将.class文件所在的路径位置编码成package的名称来实现的。按照惯例,package名称的第一部分是类的创建者的反顺序的Internet域名。如果你遵照惯例,Intemnet域名应是独一无二的,因此你的package名称也将是独一无二的,也就不会出现名称冲突的问题了(也就是说,只有在你将自己的域名给了别人,而他又以你曾经使用过的路径名称来编写Java程序代码时,才会出现冲突)。当然,如果你没有自己的域名,你就得构造一组不大可能与他人重复的组合(例如你的姓名),来创立独一无二的package 名称。如果你打算发布你的Java程序代码,稍微花点力气去取得一个域名,还是很有必要的。

此技巧的第二部分是把package名称分解为你机器上的一个目录。所以当Java程序运行并且需要加载.class文件的时候,它就可以确定.class文件在目录上所处的位置。

Java解释器的运行过程如下:首先,找出环境变量CLASSPATH(可以通过操作系统来设置,有时也可通过安装程序—用来在你的机器上安装Java或基于Java的工具—来设置)。CLASSPATH包含一个或多个目录,用作查找.class文件的根目录。从根目录开始,解释器获取包的名称并将每个句点替换成反斜杠,以从CLASSPATH 根中产生一个路径名称(于是,package foo.bar.baz就变成为fooaraz或foo/bar/baz或其他,这一切取决于操作系统)。得到的路径会与CLASSPATH中的各个不同的项相连接,解释器就在这些目录中查找与你所要创建的类名称相关的.class文件。(解释器 还会去查找某些涉及Java解释器所在位置的标准目录。)

外文原文资料信息

[1] 外文原文作者:Bruce Eckel

[2] 外文原文所在书名或论文题目:Thinking in Java (Fourth Edition)

[3] 外文原文来源:Prentice Hall, 2006, P145~P148二、外文原文资料:

Thinking in Java

Access Control

Access control (or implementation hiding) is about “not getting it right the first time.”

All good writers—including those who write software—know that a piece of work isnrsquo;t good until itrsquo;s been rewritten, often many times. If you leave a piece of code in a drawer for a while and come back to it, you may see a much better way to do it. This is one of the prime motivations for refactoring, which rewrites working code in order to make it more re

剩余内容已隐藏,支付完成后下载完整资料


资料编号:[595986],资料为PDF文档或Word文档,PDF文档可免费转换为Word

您需要先支付 30元 才能查看全部内容!立即支付

课题毕业论文、开题报告、任务书、外文翻译、程序设计、图纸设计等资料可联系客服协助查找。