访问控制权限

         ### 如果你把一个代码放到了某个位置,等过一会儿

 回头再看时,有可能会发现有更好的方式去实现相同 的功

能。这正是重构的原动力之一,重构即重写代码, 以使

得它更可读、更容易理解,并因此更具有可维护性。


          ###面向对象设计中需要考虑的一个基本问题是:

        “如何把变动的事物与保持不变的事物区分开来

          ### Java 提供了访问权限修饰词,以供类库开发人员向

客户端程序员指明哪些是可用的,哪些是不可用的。 访问控

制权限等级,从最大权限到最小权限依次为: public  、

protected 、包访问权限(没有关键字)和 private  。

         ### 如何将构件捆绑到一个内聚的类库单元中,在java 

中是使用关键字  package 加以控制。而访问权限修饰词 会因

类是存在于一个相同的包,还是存在于一个单独的包而 受到影

响。

》》包:库单元

                     ### 包内包含有一组类,它们在单一的名字空间之下

               被组织在了一起。

                    ### 如果想导入某个包下的某个类或接口,可以使用

               import 关键字 

                    ### 在 Java 中对名称空间完全控制并为每个类创建

                    唯一地标识符组合(非常重要)。

                    ### 当编写一个 Java 源代码文件时,此文件通常被

                  称为编译单元(有时也称为转译单元)。每个编译单元

                  都必须有一个后缀名 .java ,而在编译单元内则可以有

                  一个 public 类,该类的名称必须与文件的名称相同(

                  包括大小写,但不包括文件的后缀名 .java) 。每个编译

                  单元只能有一个 public 类,否则编译器就不会接受。如果

                  在该编译单元之中还有额外的类的话,那么在包之外的世界

                 是无法看见这些类的,这是因为它们不是 public  类,而且

                 它们主要用来为  public 类提供支持。

         ---------代码组织

                 ### 当编译一个  .java 文件时,在 .java 文件中的每个类都会

                       输出文件,而该输出文件的名称与 .java 文件中每个类的

                  的名称相同,只是多了一个后缀名  .class 。因此,在编译

                  少量的  .java 文件之后,会得到大量的  .class 文件。

                 ###  Java 可运行程序是一组可以打包并压缩为一个  Java  

                   文档文件(JAR,使用Java 的jar 生成器)的 .class 文件。

                   Java 解释器负责这些文件的查找、装载和解释。

                 ### 类库实际上是一组类文件。其中每个文件都有一个public

                 类,以及任意数量的非 public 类。因此每个文件都有一个构

                 件 。如果希望这些构件(每一个都有它们自己的独立的 .java

                和 .class 文件)从属于同一个群组,就可以使用关键字 

                package

                ### 如果使用 package  语句,它必须是文件中除注释以外的

                 第一句程序代码。

                ###  注意,在Java 中包的命名规则全部使用小写字母,包括

                 中间的字母也是如此。

               ### 身为一名类库设计员,很有必要牢记:package 和 import

                 关键字允许你做的,是将单一的全局名字空间分割开,使得无

                论多少人使用 Internet 以及 Java 开始编写类,都不会出现名称

               冲突的问题。

         ---------创建独一无二的包名

               ###将特定包的所有 .class  文件都置于一个文件目录下

              ### 如果你打算发布你的  Java 程序代码,取得一个域名,是很有

                     必要的。

                      (因为一般在设定包名的时候,通常是将域名反过来写,并/

                    且 是小写)

              ### Java 解释器的运行过程如下:首先,找出环境变量  CLASSPATH

                   (可以通过操作系统来设置,有时也可以通过安装程序--用来在你的

                   机器上安装 Java  或基于 Java 工具--来设置)。CLASSPATH 包含

                  一个或多个目录,用作查找 .class 文件的根目录。从根目录开始,

                  解释器获取包的名称并将每个包点替换成反斜杠,以从  CLASSPATH

                 根中产生路径名称(于是,package   foo.bar.baz   就变成为

                 foo\bar\baz  或 foo/bar/baz  或其他,这一切取决于操作系统)。得到

                的路径会与 CLASSPATH  中的各个不同的项相连接,解释器就在这些

                 目录中查找与你所要创建的类名称相关的  .class 文件(解释器还会去

                查找某些涉及  Java 解释器所在位置的标准目录)。

              ### 在使用 JAR 文件时会有一些变换。必须在类路径中将 JAR 文件的

                实际名称写清楚,而不仅是指明它所在位置的目录。

                  例如:

                CLASSPATH = . ;  D:\diannaoruanjian\jdk\lib\tools.jar

                说明:上面的类路径中,开始是一个英文的点(.)表示的是当前路径

              ### 冲突:

                     在java 类库中,可能存在同样的类名称但是它们在不同的包下

                     @@@ 可以使用单个类导入的形式来防止冲突,只要你在同一个程序

                   中没有使用有冲突的名字

                     @@@ 在使用了有冲突名字的情况下,必须返回到指定全名的方式。

         ---------定制工具库

         ---------用 import 改变行为

              ### Java 中没有 C 语言的条件编译功能。Java 中去掉此功能的原因可

                  能是因为 C 语言在绝大多数情况下是用此功能来解决跨平台问题的,

                  即程序的不同部分是根据不同的平台来编译的。由于 Java  自身可以

                  自动跨越不同的平台,因此这个功能对 Java 而言是没有必要的。

               ###    条件编译还有其他一些有价值的用途。调试就是一个很常见的

                 用途。调试功能在开发过程中是开启的,而在发布过程中是禁用的。

                 可以通过修改被导入的 package  的方法来实现这一目的,修改的方法

                 是将你程序中用到的代码从调试版改为发布版这一技术可以适用于

                 任何种类的条件代码。

         ---------对使用包的忠告

               ### 务必记住,无论何时创建包,都已经在给定包的名称的时候隐藏地

                指定了目录结构。这个包必须位于其名称所指定的目录之中,而该目录

                必须是在以  CLASSPATH  开始的目录中可以查询到的。

               ###  注意,编译过的代码通常放置在与源代码的不同目录中,但是必须

                 保证 JVM 使用  CLASSPATH  可以找到该路径

》》Java 访问权限修饰词

              ### public 、protected 和 private 这几个 Java 访问权限修饰词在使用时,

              是置于类中每个成员的定义之前的---无论它是一个域还是一个方法。每个 

              访问权限修饰词仅控制它所修饰的特定定义的访问权。

        ---------包访问权限

              ### 默认访问权限没有任何关键字,但通常是指包访问权限。

              ###由于一个编译单元(即一个文件),只能隶属于一个包,所以经由包

                     访问权限,处于同一个编译单元中所有类彼此之间都是自动可访问的。

              ###包访问权限允许将包内所有相关的类组合起来,以使它们彼此之间可

                     以轻松地相互作用。当把类组织起来放进一个包内之时,也就给它们

                     的访问权限的成员赋予了相互访问的权限,你“拥有”了该包内的程序

                     代码。

              ### 取得对某成员的访问权的唯一途径是:

                      1. 使该成员成为 public 。于是,无论是谁,无论在哪里,都可以访问

                         该成员。

                      2.通过不加访问权限修饰词并将其他类放置于同一个包内的方式给

                        成员赋予包访问权。于是包内的其他类也就可以访问该成员了。

                      3.继承技术。继承而来的类既可以访问 public 成员也可以访问

                         protected 成员(但访问 private 成员却不行)。只有两个类都处于

                         同一个包内时,它才可以访问包访问权限的成员。

                       4.提供访问器(accessor)和变异器(mutator)方法(也称get/set

                        方法),以读取和改变数值。对OOP 而言,这是最优雅的方式,而且

                        这也是  JavaBeans 的基本原理。

        ---------public :接口访问权限

              ### 不要错误地认为 Java 总是将当前目录视作是查找行为的起点之一。

                       如果你的 CLASSPATH 之中缺少了一个“.”作为路径之一的话,Java

                      就不会查找那里。

              ### 默认包:

                      给处于相同目录并且没有给自己设定任何包名称的Java 文件,看作是

                      隶属于该目录的默认包之中,于是它们为该目录中所有其他的文件都

                      提供了包访问权限。

        ---------private :你无法访问

               ### private 的意思是,除了包含该成员的类之外,其他任何类都无法访问

                    这个成员。

               ### 默认的包访问权限通常已经提供了充足的隐藏措施。请记住,使用类的

                    客户端程序员是无法访问包访问权限的成员的。这样做很好,因为默认

                   访问权限是一种我们常用的权限,同时也是一种在忘记添加任何访问权限

                   控制时能够自动得到的权限。

               ### private 的使用是非常重要的,尤其是在多线程环境下。

               ### 任何可以肯定只是该类的一个“助手”方法的方法,都可以把它指定为

                       private ,以确保不会在包内的其他地方误用到它,于是也防止了你会

                       改变或删除这个方法。将方法指定为 private 确保了你拥有这种选择权。

              ### 除非必须公开底层实现细目(此种境况很少见),否则就应该将所有

                     的域指定为 private 。然而,不能因为在类中某个对象的引用是 private ,

                     就认为其他的对象无法拥有该对象的 public 引用。

        ---------protected :继承访问权限

              ###  为了从现有的类中继承,需要声明新类  extends (扩展)了一个现有

                    的类,如下:

                    class Foo extends Bar  {

                    }

               ###有时, 基类的创建者会希望有某个特定成员,把对它的访问权限赋予

                   派生类而不是所有类。这就需要 protected 来完成这一工作。protected

                   也提供了包访问权限,也就是说,相同包内的其他类可以访问 protected

                   元素。

              ### 如果类 Cookie 中存在一个方法 bite() 的话,那么该方法同时也存在于

                   任何一个从 Cookie 继承而来的类中。如果该 bite()  方法有包访问权限

                    而且它位于另一个包内,所有我们在子类的中无法使用 bite() 方法的。

                         如果将上面的 bite() 方法的权限改为  protected 的话,在子类中就

                   可以访问父类中的  bite() 方法了。其实 protected 的权限要比包访问

                  权限要大。(将bite() 方法的权限增大了)

》》接口和实现

            ### 访问权限的控制常被称为是具体实现的隐藏。把数据和方法包装进

                  类中,以及具体实现的隐藏,常共同被称作是封装。其结果是一个同时

                   带有特征和行为的数据类型。

            ### 访问权限控制将权限的边界划在了数据类型的内部。有两个原因:

                  第一:

                        要设定客户端程序员可以使用和不可以使用的界限。可以在结构中

                 建立自己的内部机制,而不必担心客户端程序员会偶然地将内部机制

                 当作是他们可以使用的接口的一部分。

                 第二:

                         将接口和具体实现进行分离

             ### 将接口展现给某个类的使用者实际上是类浏览器的任务。类浏览器是

                     一种以非常有用的方式来查阅所有可用的类,并告诉你用它们可以做些

                     什么(也就是显示出可用成员)的工具。在 Java 中,用Web 浏览器

                     JDK 文档可以得到使用类浏览器的相同效果。

》》类的访问权限

            ### 为了控制某个类的访问权限,修饰词必须出现于关键字 class 之前。

                    例如:

                     public class Widget {

                     }

            ###  除了上面的内容,还有一些额外的限制:

                    1. 每个编译单元(文件)都只能有一个 public 类。

                    2. public 类的名称必须完全与该编译单元的文件名匹配,包括

                        大小写。

                    3. 虽然不是很常用,但编译单元内完全不带 public 类也是可能的。

                        在这种情况下,可以随意对文件命名。

            ### 类既不可以是 private 的,也不可以是 protected 的。所以对于类的

                   访问权限,仅有两个选择:包访问权限或public 。如果不希望其他

                   任何人对该类拥有访问权限,可以把所有的构造器都指定为 private ,

                   从而阻止任何人创建该类的对象,但是有一个例外,就是你在该

                   类的  static 成员内部可以创建。下面是一个示例:

                   class Soup1 {

                          private Soup1() {

                          }

                          public static  Soup1 makeSoup(){

                                return new Soup1();

                          }

                    }

            ### 请一定要牢记,如果没有明确地至少创建一个构造器的话,就会帮你

                   创建一个默认构造器(不带有任何参数的构造器)。如果我们自己编

                   写了默认的构造器,那么就不会自动创建它了。

             ### 如果没能为类访问权限指定一个访问修饰符,它就会默认得到包访问

                  权限。这就意味着该类的对象可以由包内任何其他类来创建,但是在包

                  外则是不行的(一定要记住,相同目录下的所有不具有明确 package

                  声明的文件,都被视为该目录下默认包的一部分。)然而,如果该类的

                  某个 static 成员是 public 的话,则客户端程序员仍旧可以调用该 static 

                  成员,尽管他们并不能生成该类的对象。

》》总结

          ### 对于 Java ,关键字 package 、包的命名模式和关键字 import ,可以使

                  你对名称进行完全的控制,因此名称冲突的问题是容易避免的。

          ### 控制对成员的访问权限有两个原因:

                  第一:

                            为了使用户不要触碰那些他们不该碰触的部分,这些部分对于

                  类内部的操作是必要的,但是它并不属于客户端程序员所需接口的一

                  部分。因此,将方法和域指定成 private ,对客户端程序员而言是一种

                  服务。 

                  第二:(也是最重要的)

                             为了让类库设计者可以更改类的内部工作方式,而不必担心这样

                   会对客户端程序员产生重大的影响。

         ### 注意,访问权限控制专注于类库创建者和该类库的外部使用者之间的关系,

                 这种关系也是一种通信方式。

猜你喜欢

转载自blog.csdn.net/lierming__/article/details/79814103