Java 使用包组织类

本文最后更新于:2024年3月18日 凌晨

Java 使用包组织类

  • Java中的所有资源也是以文件方式组织的,其中主要包含大量的类文件,它们也需要组织管理,Java采用了包来组织类,与操作系统的目录树形结构一样,但Java中采用了","来分隔目录,通常将逻辑相关的类放在同一个包中,包将类的命名空间进行了有效划分,同一包中不能有两个同名的类。
  • Java系统提供的类库也称为Java API,它是系统提供的已实现的标准类的集合,根据功能的不同,Java类库按其用途被划分为若干个不同的包,每个包都有若干个具有特定功能和相互关系的类(class)和接口(interface),在J2SE中可以将Java API的包分为3部分,即"java.*"包,,"javax.*"包和"org.*"包,其中第一部分称为核心包(以java开头),主要子包有applet,awt,beans,io,lang,math,net,sql,text,util等;第二部分又称为java拓展包(以javax开头),主要子包有swing,security,rmi等;第三部分不妨称为组织扩展包,主要用于CORBA和XML处理等。
  • 要使用某个类必须指出类所在包的信息,这点与访问文件需要指定文件需要指定文件路径是一样的,例如,以下代码将使用java.util包中Date类创建一个代表当前日期的日期对象,并将该对象的引用赋值给变量x:
1
java.util.Date x = new java.util.Date();
  • 实际上,在java.sql包中也包括一个Date类,因此,使用类必须指定包路径。
  • 使用系统类均需给出全程路径无疑用户会觉得麻烦,为此,Java提供了import语句引入所需的类,然后在程序中直接使用类名来访问类,使用形式如下:
1
2
3
4
import java.util.Date;

...
Date x = new Date();

建立包

  • 在默认情况下,系统会为每一个源文件创建一个无名包,这个源文件创建一个无名包,这个源文件中定义的所有类都隶属于这个无名包,它们之间可以相互作用非私有的域或方法,但无名包中的类不能被其他包中的类所引用,因此,如果希望编写的类被其他包中的类引用,则要建立有名包。
  • 创建包的语句需要使用关键字package,而且要放在源文件的第1行,每个包对应一条目录路径,例如,以下定义test包就意味着在当前目录下对应有一个test子目录,该包中所有类的字节码文件将存放在test子目录下,在文件Point.java中包含如下代码:
1
2
3
4
package test;// 定义包。
public class Point{
...
}
  • 在DOS下,要编译带包的Java程序有两种方法:
  1. 手工创建一个test子目录,将源程序文件存放到该子目录,在该子目录的上级目录下利用以下命令编译,也就是编译时要指明源程序的目录路径。
1
javac test/Point.java
  1. 也可以直接在子目录中编译源程序。
  • 例如,Point类含main()方法,则类执行时需加包路径,例如:
1
java test.Point
  • 采用带路径指示的编译命令:
1
javac -d destpath Point.java
  • 其中,desppath为存放应用的主类文件的根目录路径,编译器将自动在destpath指定的目录下建一个test子目录,并将产生的字节码文件保存到test子目录下。
  • 典型的用法是在当前目录下进行编译,则命令为:
1
javac -d . Point.java
  • 编译后将源程序文件Point.java移动到test子目录中。
  • 在Eclipse等Java开发环境中,在工程的src文件夹下建立的子文件夹,将自动对应Java程序的包路径,在各子文件夹下添加的Java程序在自动产生代码时将默认添加对应的包定义,系统环境会自动进行相关源程序的编译检查。

包的引用

  • 在一个类中可以引用与它同一个包中的类,也可以引用其他包中的public类,但这时要指定包路径,具体有以下几种方法:
    • 在引用类时使用包名作为前缀,例如"new java.util.Date()"
    • 用import语句加载需要使用的类,在程序开头用import语句加载要使用的类,例如"import.java.util.Date";然后在程序中可以直接通过类名创建对象,例如"new Date()"
    • 用import语句加载整个包,用"*“号代替类名位置,它将加载包中的所有类,例如"import java.util.*;”
  • 注意
    • import语句加载整个包并不是将包中的所有类添加到程序中,而是告诉编译器使用这些类时到什么地方去查找类的代码,在某些特殊情况下,两个包中可能包含同样名称的类,例如java.util和java.sql包中均包含Date类,如果程序中同时引入了两个包,则不能直接用new Date()创建对象,而要具体指定包路径。
    • 通过设置环境变量CLASSPATH指明字节码文件路径。
    • Java通过CLASSPATH环境变量定义类的查找路径,在Java中常把一棵类树压缩成一个.jar文件,在指定环境变量时可以指定.jar文件所在目录,也可以具体指明.jar的完全查找路径,在有些情况下,由于CLASSPATH的值中不包含当前目录,在执行java命令时你也许会发现类文件找不到,这时可修改系统环境变量CLASSPATH的值使其包含代表当前目录的"."项目。
    • 要设置CLASSPATH,可修改系统的环境变量或使用如下DOS命令:
1
SET CLASSPATH=.;C:\JDK1.7\lib\dt.jar;c:\JDK1.7\lib\tools.jar

[例5-6]:编写一个代表圆的类,其中包括圆心(用Point表示)和半径两个属性,利用本章Point类提供的方法,求两个圆心间的距离,编写一个静态方法判断两个圆是否外切,用两个实际圆验证程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 引入test包中的Point类。
import test.Point;
public class Circle{
Point center;
double r;

public Circle(Point p,double r){
center = p;
this.r = r;
}

public static boolean isCircumscribe(Circle c1,Circle c2){
return (Math.abs(c1.center.distance(c2.center)-c1.r-c2.r)<0.00001);
}

public String toString(){
return "\"圆心是"+center+"半径="+r+"\"";
}

public static void main(String args[]){
Point a = new Point(10,10);
Point b = new Point(30,20);
Circle c1 = new Circle(a,10);
Circle c2 = new Circle(b,5);
if(isCircumscribe(c1,c2))
System.out.println(c1+" 和"+c2+"的两圆相外切");
else
System.out.println(c1+" 和"+c2+"的两圆不外切");
}
}

"圆心是点: 10,10,半径=10.0""圆心是点:30,20,半径=5.0"的两圆不外切。
  • 说明:本例演示了参数和属性均含有复合类型的情形,代表圆心的属性为Point属性,第9行定义的圆的外切判断判定方法中的两个参数是Circle类型,第20行调用该方法时将两个圆对象作为实参传递给方法,判定两圆外切是用圆心间的距离减去两半径之和的绝对值是否小于误差值作为条件。
  • 注意:如果一个程序中同时存在package语句,import语句和类定义,则排列次序是:package语句为第一条语句,接下来是import语句,然后是类定义。

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!