Java编程思想(六、访问权限控制)
访问控制(或隐藏具体实现)与“最初的实现并不恰当”有关。便于未来重构代码,而不必对业务层做过多的改变。因此,Java提供了访问控制修饰词,以供类库开发人员向客户端程序员指明哪些是可用的,哪些是不可用的。
访问控制的等级,从最大权限到最小权限依次为:public、protected、包访问权限(没有关键词)、和private。
1、包:类库单元。包内含有一组类,它们在单一的名字空间之下被组织在了一起。比如,在Java的标准发布中有一个工具库。它被组织在java.util名字空间之下。java.util有一个叫做ArrayList的类,使用ArrayList的一种方式是用其全名
java.util.ArrayList 或者转而使用 import关键字。先导入,再使用。 我们之所以要导入,就是要提供一个管理名字空间的机制,所以类成员的名称都是彼此隔离的。A类中的方法f()与B类中具有相同特征标记(参数列表)的方法f()不会彼此冲突。
当编写一个Java源代码文件时,此文件通常被称为编译单元(有时也被称为转译单元)。每个编译单元都必须有一个后缀名.java。而在编译单元内则可以有一个public类,该类的名称必须与文件的名称相同(包括大小写。但不包括后缀名.java)。每个编译单元只能由一个public类,否则编译器就不会接受。如果在该编译单元中还有额外的类的话,那么在包之外的世界是无法看见这些类的,这是因为它们不是public类,而且它们主要用来为主public类提供支持。
在java中,可运行程序是一组可以打包并压缩为一个Java文档文件(JAR,使用Java的jar文档生成器)的.class文件。Java解释器负责这些文件的查找、装载和解释。
类库实际上是一组类文件。其中每个文件都有一个public类,以及任意数量的非public类。因此每个文件都有一个构件。如果希望这些构件(每一个都有他们的独立的.java和.class文件)从属于同一个群组,就可以使用关键字package。
介绍一下Java解释器的运行过程:首先,找出环境变量CLASSPATH。CLASSPATH包含一个或多个目录,用作查找.class文件的根目录。从根目录开始,解释器获取包的名称并将每个句点替换成反斜杠,用以CLASSPATH根中产生一个路径名称。得到的路径会与CLASSPATH中的各个不同的项相连接,解释器就在这些目录中查找与你所要创建的类名称相关的.class文件。
用import改变行为。Java没有C的条件编译功能,该功能可以使你不必更改任何程序代码,就能够切换开关并产生不同的行为。但Java没有此功能,因为大多C使用这个功能是为了实现跨平台,但Java有虚拟机,自动可以跨平台。条件编译还有另一个功能,那就是调试。调试功能在开发过程中是开启的,而在发布的产品中是禁止的。可以通过修改被导入的package的方法来实现这一目的。比如创建两个包,一个是debug一个是debugoff。它们都包含一个相同的类,该类有一个debug()方法。第一个版本显示发送给控制台的String参数,第二个版本什么都不做。以后就能通过导入不同的类,实现不同的行为了。
2、Java访问权限修饰词。
1)包访问权限。如果不提供任何访问权限修饰词,则意味着它是“包访问权限”。这意味着当前的包中的所有其他类对那个成员都有访问权限,但对这个包之外的的所有类,这个成员却是private的。
一般来说取得某成员的访问权的唯一途径是:1、使该成员成为public 2、通过不加访问权限修饰词并将其他类放置在同一个包内。获得包访问权。3、继承。但是只能访问public以及protected的。4、提供访问器(accessor)和变异器(mutator)方法(也就是set、get),以读取和改变数值。
2)public:接口访问权限。使用关键字public,就意味着public之后紧跟着的成员声明自己对每个人都是有用的。
默认包:
class Cake{ public static void main (String[] args){ Pie x = new Pie(); x.f(); } }
clsaa Pie{ void f(){} }
或许看起来这两个文件毫无关系,但是它们处在相同的目录并且没有给自己设定任何包名称。这样Java会将这样的文件自动看作是隶属于该目录的默认包之中。
3)private:你无法访问。除了包含该成员的类之外,其他任何类都无法访问这个成员。同处于一个包内的其他类也是不能够访问private成员的。如果将类的构造器都是private的,那么它将阻碍对此类的继承。
4)protected:类的创建者可以将某个特定成员。把它的访问权限赋予给派生类而不是所有类。protected也提供包访问权限。相同包内的其他类可以访问protected元素。
3、接口和实现。访问权限的控制常被称为是具体实现的隐藏。把数据和方法包装进类中,以及具体实现的隐藏,常共同被称为是封装。访问权限控制将权限的边界划在了数据类型的内部。第一个原因是要设定客户端程序员可以使用和不可以使用的界限。可以在结构中建立自己的内部机制,而不必担心客户端程序员会偶然地将内部机制当作是他们可以使用的接口的一部分。第二个原因就是接口和具体实现的分离。如果结构是用于一组程序之中,而客户端程序员除了可以向接口发送信息之外什么也不可以做,那么就可以随意更改所有不是public的东西,而不会破坏客户端的代码。
4、类的访问权限。控制类的访问权限。修饰词必须出现在关键字class之前。类的访问权限只有两个选择,包访问权限或者是public。如果不希望别人访问你的类,你可以将所有构造器都指定为private,从而阻止任何人创建该类的对象。但是没法阻止你自己创建对象,你可以在该类的static成员内创建。