Java编程思想第四版——第十九天

2012-05-02

149-158/913

 

Java编程思想第四版——第十九天

 

1.1        java访问权限修饰词

public、protected和private这几个java访问权限修饰词在使用时,是置于类中每个成员的定义之前的——无论它是一个域还是一个方法。每个访问权限修饰词仅控制它所修饰的特定定义的访问权。

 

如果不提供任何访问权限修饰词,则意味着它是“包访问权限”。因此,无论如何,所有事物都具有某种形式的访问控制权限。

 

6.2.1 包访问权限

一个编译单元(即一个文件),只能隶属于一个包,所以经由包访问权限,处于同一个编译单元中的所有类彼此之间都是自动可访问的。

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

  1. 使该成员成为public。无论是谁,无论在哪里,都可以访问该成员。
  2. 通过不加访问权限修饰词并将其他类放置于同一个包内的方式给成员赋予包访问权。于是包内的其他类也就可以访问该成员了。
  3. 继承而来的类既可以访问public成员也可访问protected成员(但不能访问private成员)。只有两个类都处于同一个包内时,它才可以访问包访问权限的成员。
  4. 提供访问器(accessor)和变异器(mutator)方法(也称作get/set方法),以读取和改变数值。对OOP而言,这是最优雅的方式,而且这也是JavaBeans的基本原理。

 

1.1.2          public:接口访问权限

使用public,就意味着public之后紧跟着的成员声明自己对每个人都是可用的,尤其是使用类库的客户程序员更是如此。

 

不要错误的认为java总是将当前目录视作是查找行为的起点之一,如果CLASSPATH缺少一个“.”作为路径之一的话,java就不会查找当前目录了。

 

默认包:

为了使文件可以被编译,在CLASSPATH之中一定要有“.”。

Java将同处于相同的目录并且没有给自己设定任何包名称的文件自动看作是隶属于该目录的默认包之中,并为该目录中所有其他的文件都提供了包访问权限。

 

1.1.3          private:你无法访问

关键字private的意思是,除了包含该成员的类之外,其他任何类都无法访问这个成员。

多线程环境下,private的使用很重要。

 

Private可以用到的地方:想控制如何创建对象,并阻止别人直接访问某个特定的构造器(或全部构造器),把类的构造器声明成private的,让后用一个方法来获得该对象。

默认构造器是唯一定义的构造器,并且是private的,那么它将阻碍对此类的继承。

 

1.1.4          protected:继承访问权限

关键字protected处理的是继承的概念,通过继承可以利用一个现有类——我们将其称为基类,然后将新成员添加到该现有类中而不必碰该现有类。还可以改变类的现有成员的行为。为了从现有类中继承,需要声明新类extends(扩展)了一个现有类。

例如:class Foo extends Bar

类定义中的其他部分看起来都是一样的。

 

protected也提供包访问权限。

 

1.2        接口和实现

访问权限的控制常被称为是具体实现的隐藏。

把数据和方法包装进类中,以及具体实现的隐藏,常共同被称作是封装。其结果是一个同时带有特征和行为的数据类型。

出于两个很重要的原因,访问权限控制将权限的边界划在了数据类型的内部。第一个原因是要设定客户端程序员可以使用和不可以使用的界限。可以在结构中建立自己的内部机制,而不必担心客户端程序员会偶然地将内部机制当作是他们可以使用的接口的一部分。

这个原因直接引出了第二个原因,即将接口和具体实现进行分离。如果结构是用于一组程序之中,而客户端程序员除了可以向接口发送信息之外什么也不可以做的话,那么就可以随意更改所有不是public的东西(例如有包访问权限、protected和private的成员),而不会破坏客户端代码。

 

类浏览器可以将接口展现给某个类的使用者。

 

1.3        类的访问权限

在java中,访问权限修饰词也可以用于确定库中的哪些类对于该库的使用者是可用的。

可以控制是否能创建一个该类的对象。

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

访问public类:

public class Widget{

通过下面的声明访问:

import access.Widget;

或import access.*;

有一些额外的限制:

  1. 每个编译单元(文件)都只能有一个public类。这表示,每个编译单元都有单一的公共接口,用public类来表现。该接口可以按要求包含众多的支持包访问权限的类。如果在某个编译单元内有一个以上的public类,编译器就会给出出错信息。
  2. Public类的名称必须完全与含有该编译单元的文件名相匹配,包括大小写。
  3. 编译单元内完全不带public类也是可能的,这种情况下,可以随意对文件命名。

 

创建一个包访问权限的类时,仍旧是在将该类的域声明为private时才有意义——应尽可能地总是将域指定为私有的,但是通常来说,将与类(包访问权限)相同的访问权限赋予方法也是很合理的。

类既不可以是private的(这样会使得除该类外,其他任何类都不可以访问它),也不可以是protected的(一个内部类可以是private或是protected的,这是一个特例)。对于类的访问权限,仅有两个选择:包访问权限或public。如果不希望其他任何人对该类拥有访问权限,可以把所有的构造器都指定为private,从而阻止任何人创建该类的对象,有一个例外,在该类的static成员内部可以创建。

 

方法中void意思是不返回任何东西。也可以返回一个对象引用。

 

Singleton(单例):

class Singleton{

       private Singleton(){
       }

      

       private static Singleton s = new Singleton();

      

       public static Singleton getSingleton(){

              return s;

       }

}

始终只能创建它的一个对象,类的对象是作为一个private static成员而创建的,有且仅有一个,除非是通过getSingleton()方法,否则是无法访问到它的。

 

如果没能为类访问权限指定一个访问修饰符,就会默认得到包访问权限。这就意味着该类的对象可以由包内任何其他类来创建,但在包外则是不行的。(相同目录下的所有不具有明确package声明的文件,都被视作是该目录下默认包的一部分。)如果该类的某个static成员是public的话,客户端程序员仍旧可以调用该static成员,尽管他们并不能生成该类的对象。

 

1.4        总结

无论是在什么样的关系之中,设立一些为各成员所遵守的界限始终是很重要的。

本章讨论了类是如何被构建成类库的:首先,介绍了一组类是如何被打包到一个类库中的;其次,类是如何控制对其成员的访问的。

 

C语言仅有单一的“名字空间”,代码多了就可能发生名称冲突,引发额外的管理开销。对于java,关键字package、包的命名模式和关键字import,可以使名称进行完全的控制,因此名称冲突的问题是很容易避免的。

 

控制对成员的访问权限有两个原因。第一是为了使用户不要触碰那些他们不该触碰的部分,这些部分对于类内部的操作是必要的,但是它并不属于客户端程序员所需接口的一部分。第二个原因,很重要的原因,是为了让类库设计者可以更改的内部工作方式,而不必担心这样会对客户端程序员产生重大的影响。

 

注意,访问权限控制专注于类库创建者和该类库的外部使用者之间的关系,这种关系也是一种通信方式。然而,在许多情况下事情并非如此。例如,自己编写了所有的代码,或者在一个组员聚集一起的项目组中工作,所有的东西都放在同一个包中。这些情况是另外一种不同的通信方式,因此严格的遵循访问权限规则并不一定是最佳选择,默认(包)访问权限也许更可行。

 

下一章复用类。

posted @ 2012-05-02 11:09  凌紫冥  阅读(242)  评论(0编辑  收藏  举报