转载自 http://blog.csdn.net/itdo_just https://blog.csdn.net/itdo_just/article/details/79321361
为了更好地组织类,Java提供了包机制。包是类的容器,用于分隔类名空间。如果没有指定包名,所有的示例都属于一个默认的无名包。在包的基础上再引入权限的概念,它包含类的访问权限和类成员的访问权限。
下面先以程序来说明一下 JAVA 中包的概念。
/* 包的关键字“package” */
/* 这个 Pack 类会存放在 a/b/c/d 这个四级目录的d目录下 */
package a.b.c.d;
public class Pack {
public static void main(String args[]) {
System.out.println("Hello World!");
}
}
编译这段代码需要使用指令:
javac -d . Pack.java
运行这段代码使用:
java a.b.c.d.Pack
代码非常简单就是打印字符串,但是使用 package 这个关键字后我们可以指定这个类放入哪个文件夹(即包)里面。有什么用呢,如果一个工程下面有多个同名类,那么可以使用 import 来导入具体调用哪个包下面的类,如下代码实现:
先写两个类,它们处于不同的包名下面:
/* 处于d1这个包 */
package a.b.c.d1;
public class Math {
public static int add(int x, int y) {
return x + y;
}
}
/* 处于d2这个包 */
package a.b.c.d2;
public class Math {
public static int sub(int x, int y) {
return x - y;
}
public static int add(int x, int y) {
return x + y + 2;
}
}
每个文件夹我们可以创建多个类,比如在 d2 这个包下再创建一个:
/* 也处于d2这个包 */
package a.b.c.d2;
public class Print {
public static void printInfo() {
System.out.println("package: a.b.c.d2");
}
}
下面是对这些包的调用,使用 import 关键字来导入后便可使用它们包下的类
/* import 表示导入,下面导入这个(d1、d2)目录下的所有类 */
import a.b.c.d1.*;
import a.b.c.d2.*;
public class Pack {
public static void main(String args[]) {
/* add */
System.out.println(a.b.c.d1.Math.add(1, 2));
System.out.println(a.b.c.d2.Math.add(1, 2));
/* sub */
System.out.println(a.b.c.d2.Math.sub(2, 1));
a.b.c.d2.Print.printInfo();
/* 如果没有同名的类,也可以直接使用下面的调用方式 */
Print.printInfo();
}
}
在将这个程序进行编译后,在各个包下就会生成对应的类,但是有个问题,假如将这个程序交给客户,我们不仅要给 Pack.java 给客户,还得把整个包目录也交给客户,这样就会比较麻烦,你给个程序,还需要给这么多目录文件,有没有办法呢,当然是有的,我们可以将包进行打包,我在 java 虚拟机下使用 jar 命令可以对包进行打包(具体使用 jar -help 看帮助说明),使用
jar -cf my.jar a
这个命令对 a 这个包进行压缩,命名为 my.jar,之后便可删除 a 目录,在执行程序时,只需要将这个包添加到环境变量里面即可,具体使用 CLASSPATH(编译的时候用来查找代码,运行的时候来查找文件和压缩包),当然在此之前我们也可以使用命令先查看下这个类去哪里查找这些源代码的,使用如下命令:
javac Pack.java -verbose
在进行打包编译后,我们使用如下命令把压缩包添加进环境变量
export CLASSPATH=.:my.jar
表明在当前目录(.)和(my.jar)这个目录下查找,再次编译即可成功,这样以后给客户只需要提供类和这个压缩包就可以了。
在了解了包的概念后,就可以很好的讲解权限的问题了,java 下的权限分两种,一个是类权限,一个是类成员权限,类权限有 public class 和 class ,类成员权限有 private、default、protected、public 这四种,下面以程序来分别讲解上述的几种权限。
首先定义一个类,它处于 b 包下,这个类的权限为 “public”
package b;
/* public 表示这个类本程序内和本包内都可以访问,外包也能访问 */
/* 如果没有定义 public , 本程序内和本包内都可以访问,但外包不能访问*/
public class Mymath{
}
试验一下,在 a 包里面来访问这个 b 包里面的类
package a;//这个类放到a目录里面
import b.*;//b里面所有类引进来
public class Pack{
public static void main(String args[]) {
Mymath m = new Mymath();
}
}
上面程序运行完全没有问题,但如果去掉了 public 关键字的话就只能本包内访问,而 a 包是无法访问到 b 包里面的类的。
接下来再说下“类成员”的访问权限。先在同一个包内创建一个类,类里面的成员权限为 “private”
package a;
class Mymath{
private int x;//私有权限
}
再有一个同包的类,如下
package a;//这个类也放到a目录(包)里面
public class Pack{
public static void main(String args[]) {
Mymath m = new Mymath();
/* 下面这步操作肯定出错,因为x 是 Mymath 的私有成员,
只能在同一个类里面去访问 */
m.x = 0;
}
}
类的成员权限如果为“default”,如下:
package a;
class Mymath{
int x1;/* 默认权限:default */
}
再有一个同包的类,如下
package a;//这个类也放到a目录(包)里面
public class Pack{
public static void main(String args[]) {
Mymath m = new Mymath();
/* 下面这一步没有问题,因为 defualt 权限同一个包内能访问,但不同包内不行 */
m.x1 = 0;
}
}
还有个类成员权限类型为 “protected”,什么范围呢,如下程序所示:
package b;
//public 表示能访问这个类,但是能不能访问类的成员取决于成员的权限
public class Mymath{
protected int x1;/* protected:受保护的权限 */
}
再有一个不同包的类:
package a;//这个类放到 a 目录(包)里面
import b.*;//导入 b 里面所有类
/* 作为 Mymath 子类(b包里面),它里面可以去访问b里面的 protected 成员变量 */
class Mysubmath extends Mymath {
/* protected 在不同包内只能在子类里面进行访问,同包的话就没有限制 */
void printInfo() {
/* 访问 b 包里面 Mymath 类的 x1 这个成员,毫无问题 */
System.out.println("Mysubmath : x1 = "+x1);
}
}
public class Pack{
public static void main(String args[]) {
Mysubmath m = new Mysubmath();
//m.x1 = 0;//protected只能在不同包的子类可以调用,这不是子类,错误
m.printInfo();//这里只能通过本包子类的方法间接去调用
}
}
还剩一个 public 就没什么好讲的了, 所有的包都能直接访问。
最后用思维导图做个总结,上面的权限会以图示出来,也更加分明