Java编程思想——访问权限控制

来源:互联网 发布:json.parsearray 编辑:程序博客网 时间:2024/06/05 11:19

6. 访问权限控制

如何把变动的事物与不变动的事物区分开来是面向对象设计中需要考虑的一个基本问题。在修改和完善代码的压力下,如何保证某些代码是不可变动,哪些是有权限可以变动的。为了解决这一问题,java提供了访问权限修饰词,供类库开发人员向客户端程序员指明哪些是可用的,哪些是不可用的,权限等级从大到小依次为:public、protected、包访问权限(默认)、private。

6.1 包:库单元

包内含有一组类,它们在单一的名字空间下被组织在了一起
例如在java标准发布中有一个工具库,它被组织在java.util名字空间之下。java.util中有一个叫做ArrayList的类。使用ArrayList的一种方式是使用全名。

public class FullQualification{    public static void main(String[]args){    java.util.ArrayList list = new java.util.ArrayList();    }}

另一种方式就是使用import语句

import java.util.ArrayList;public class FullQualification{    public static void main(String[]args){    java.util.ArrayList list = new ArrayList();    }}

如果想导入util包下的其他类,可以使用import java.util.*;
导入包的意义是提供一个管理名字空间的机制。所有类成员的名称是彼此隔离的。

当编写一个java源代码文件时,此文件通常被称为编译单元,每个编译单元都必须有一个后缀名为.java,而在编译单元内则有一个public类,类的名称与文件名相同。

6.1.1 代码组织

当编译一个.java文件,在.java文件中每一个类都会有一个输出文件,而该输出文件的名称与.java文件中每个类的名称相同,只是多了一个后缀名.class。因此编译一个少量.java文件,会得到大量的.class文件。Java可运行程序是一组可以打包并压缩为一个java文档文件的.class文件。java解释器负责这些文件的查找,装载和解释。

类库实际上是一组类文件,每个文件都有一个public类,以及任意数量的非public类。每个文件都有一个构件。如果希望这些构件从属于一个群组,就可以使用关键字package。

如果使用package语句,必须是文件中除注释外第一句程序代码。例如:
package acess;表明你声明该编译单元是名为access类库中的一部分。如果想使用access类库下的任何类,可以使用import语句或者使用完整名称。

6.1.2 独一无二的包名

包是有许多.class文件构成。可以将特定包下的所有.class文件都置于一个目录下。这里需要解决两个问题:怎样创建独一无二的名称以及怎么查找有可能隐藏于目录结构中某处的类。

按照惯例,package的名称的第一部分是类的创建者的反顺序的Internet域名。如果没有自己的域名,就得构造一组不大可能与他人重复的组合(例如姓名)。如果你打算发布你的java程序代码,还是有必要获得一个域名。

第二个部分就是将package名称分解为你机器上的一个目录。
java解释器的运行过程:找出环境变量CLASSPATH(其包含一个或多个目录,用作查找.class文件的根目录。)从根目录开始,解释器获取包的名称并将每个句点替换成反斜杠,以从CLASSPATH根中产生一个路径名称。得到的路径会与CLASSPATH的各个不同的项相连接,解释器就在这些目录中查找与你所要创建的类名称相关的.class文件。

6.1.3 定制工具库

具备前述知识,可以创建自己的工具来减少或消除重复的程序代码了。例如自己创建一个print的类来简化输出

//: net/mindview/util/Print.java// Print methods that can be used without// qualifiers, using Java SE5 static imports:package net.mindview.util;import java.io.*;public class Print {  // Print with a newline:  public static void print(Object obj) {    System.out.println(obj);  }  // Print a newline by itself:  public static void print() {    System.out.println();  }  // Print with no line break:  public static void printnb(Object obj) {    System.out.print(obj);  }  // The new Java SE5 printf() (from C):  public static PrintStream  printf(String format, Object... args) {    return System.out.printf(format, args);  }} ///:~

6.1.4 使用包的忠告

无论何时创建包,都已经在给定包的名称的时候隐含地指定了目录结构。这个包必须位于其名称所指定的目录之中,而该目录必须是在以CLASSPATH开始的目录中可以查询到。编译过的代码一般放在与源代码的不同目录中。

6.2 java访问权限修饰词

public、protected、private这几个java访问权限修饰词在使用时是置于类中的每个成员的定义之前的——无论它是一个域还是一个方法。如果不提供任何访问权限修饰词,意味着它是包访问权限修饰词。

修饰符 类内部 同一个包 子类 任何地方 private YES (缺省) YES YES protected YES YES YES public YES YES YES YES

6.2.1 包访问权限

默认访问权限没有任何关键字,即指包访问权限。意味着当前包中的所有其他类对那个成员都有访问权限,但对于这个包之外的所有类,这个成员却是private。一个编译单元只能隶属于一个包,所以经由包访问权限,处于同一个编译单元中的所有类彼此之间都是可以访问。

类控制着哪些代码可以有权访问自己的成员。取得对某成员访问的唯一途径是:

  1. 使该成员为public。
  2. 通过不加访问权限修饰符并将其他类放置于同一个包内的方式给成员变量赋予包访问权限。于是包内的其他类也可以访问该成员
  3. 下一章的继承技术
  4. 提供访问器(accessor)和变异器(mutator)方法(也称get/set方法)

6.2.2 public:接口访问权限

使用关键字public,意味着public之后紧跟着的成员声明自己对每个人都是可用的。尤其是使用类库的客户端程序员。
注意默认包:如果类没有声明自己所在的包,java将这样的文件看作是隶属于该目录的默认包之中。

6.2.3 private: 你无法访问

关键字private的意思是:除了包含这个成员的类之外,其他任何类都无法访问这个成员。处于同一个包内的其他类是不可以访问private成员的,等于说自己隔离了自己。

默认的包访问权限通常已经提供了充足的隐藏措施。使用类的客户端程序员是无法访问包访问权限成员的。默认访问权限是一种我们常用的权限,同时也是一种忘记添加任何访问权限控制的自动得到的权限。

任何可以肯定知识该类的一个助手方法的方法,都可以把它指定为private,以确保不会再包内的其他地方误用到它,防止了你会去改变和删除这个方法。对于类中的private域同样适用。除非必须公开底层实现细目,否则就将所有的域指定为private。不能因为在类中某个对象的引用是private,就认为其他的对象无法拥有该对象的public引用。

6.2.4 protected: 继承访问权限

关键字protected处理的是继承的概念,通过继承可以利用一个现有的类——基类,然后将新成员添加到该类中而不必碰该现有类。还可以改变该类的现有成员的行为。为了从现有类中继承,需要声明新类extends了一个类:
class Foo extends Bar{}
如果创建了一个新包,并自另一个包中的继承类,那么唯一可以访问的成员就是源包的public成员。基类的创建者希望有某个特定的成员,把对它的访问权限赋予派生类而不是所有类,这就需要protected来完成这一个工作。

//: access/cookie2/Cookie.javapackage access.cookie2;public class Cookie {  public Cookie() {    System.out.println("Cookie constructor");  }  protected void bite() {    System.out.println("bite");  }} ///:~//: access/ChocolateChip2.javaimport access.cookie2.*;public class ChocolateChip2 extends Cookie {  public ChocolateChip2() {   System.out.println("ChocolateChip2 constructor");  }  public void chomp() { bite(); } // Protected method  public static void main(String[] args) {    ChocolateChip2 x = new ChocolateChip2();    x.chomp();  }} /* Output:Cookie constructorChocolateChip2 constructorbite*///:~

6.3 接口和实现

访问权限的控制常被称为“具体实现的隐藏”。把数据和方法包装进类中,以及具体实现的隐藏,常共同被称作是“封装”。结果是一个同时带有特征和行为的数据类型。
关于接口实现后面讨论到接口详细讲解。

6.4 类的访问权限

访问权限修饰符可以确定哪些类对于该类库的使用者是可用的。对于class的权限修饰只可以用public 和default(缺省)
 public类可以在任意地方被访问。
 default类只可以被同一个包内部的类访问。

原创粉丝点击