
任务3.2 包
创建Car.java包,在此包中定义Bus类、Truck类和Taxi类;创建test.java包,在此包中定义一个CarTest类,来测试包Car.java的用法。

3-7 包的声明
知识储备
3.2.1 包的声明
一个Java项目包含很多个模块,这些模块分别由不同的开发人员完成,每个开发人员需要定义很多个类来实现模块的功能。那么,开发人员在对类进行命名的时候,由于不知道其他人对类的命名情况,很可能会发生类同名的现象。为了解决类名冲突的问题,需要用包(Package)来实现。
包是Java提供的一种为了更好地组织类而建立的命名空间机制,把一组功能相关的类和接口组织在一起,放在同一个包中。同一个包的类名必须是不同的,但不同的包中的类名是可以相同的,当同时调用两个包中具有同名的类时,在类名的前面加上包名加以区分,这样可以避免类名冲突问题。
包定义了软件单元,相当于系统中的文件夹,它能够独立发布,并能够与其他包一起组成一个应用程序。包是相关类与接口的集合,例如,String类位于java.lang包中,Scanner类包含在java.util包之中。包是比类更大的一个程序单元,并且包提供了命名空间和访问权限的管理。使用包的好处如下所述。
● 方便了解哪些类和接口是相关的,也方便按功能查找类和接口。
● 包创建了一个“命名空间”,以避免类型之间的命名冲突。一个包中的类名、接口名不会与其他包中的类名和接口名发生冲突。利用包也方便对编写的程序进行管理。
● 允许包中的类比较自由地访问包中的其他类,同时又比较严格地限制包外面的类对包内的类进行访问。
代码文件中的包声明指定了该代码所属包的名称。包声明语句必须在代码文件中的所有类声明的前面。除了注释语句之外,包声明语句是Java代码文件的第一条语句,也就是说,它只能写在代码的第一行。创建包就是在当前文件夹下创建一个子文件夹,以便存放这个包中包含的所有类的.class文件。包使用关键字package进行声明,语法格式如下。

包名必须符合Java标识符的命名规则,按照习惯,包名一般使用小写字母。在使用Java开发项目的时候,不同项目的两个程序员很可能为两个不同的包取了相同的名字,为了避免混淆,可以使用表示从属关系的层次结构来命名包。例如,可以使用“公司域名.项目名.模块名.代码块名”这样的形式,如下所示。

若类名以包名作为其前缀,则称其为该类的全限定名,如String类的完全限定名是“java.lang.String”。
使用包的更重要的意义是,给每个包创建了一个新的命名空间。利用包可以方便地根据功能找到相关的类。Java中常用的包如下。
● java.lang:语言包,包含了基本的类和接口。
● java.util:包含实用工具类和接口,如各种常用的数据结构、字符串及日期和时间等。
● java.awt:抽象窗口工具包,包含创建和维护图形窗口的所有类和接口,是Java最早用于编写图形界面应用程序的开发包。
● java.swing:在java.awt包基础上提供的新的界面工具包,比java.awt包中相应的组件更灵活,更易于使用。但是,事件的响应等工作还是要用java.awt包来完成。
● java.io:包含输入、输出相关的类。
● java.applet:小程序包,包含与Applet相关的几个类和接口,可以创建Applet,用浏览器与Applet交互,并播放声音片段。
● java.sql:包含向数据库发送SQL语句的类。
一个类只能属于一个包,默认的是一个无名包。当定义一个类文件的时候,在没有选择所属包的情况下,该类就属于系统默认包(Default Package)。一般来说,一个稍具规模的应用程序都应该把所有定义的类划分到几个包中,每个包对应该应用程序的一个子系统。
包可以嵌套,在一个包内部声明的包称为该包的子包,子包下面还可以再声明自己的子包。声明一个子包的语法格式如下。

方括号表示括号中的项是可选的。在一个包中所包含的包称为子包,而包含子包的包称为上层包。一个子包的包名和它的所有上层包的包名构成的包名被称为该子包的全限定名。例如,java.lang就是一个嵌套包,包lang嵌套在更大的包java中。包的嵌套可以对一些相关的包进行具有层次结构的命名组织方法,以便于程序员查找某个类,并不提供包之间的特殊访问能力。从编译器角度来看,嵌套包之间没有任何关系。
包被映射到程序所对应的存储路径下的目录结构上,一个包名就是一个目录名,它的子包名是一个子目录名,该子包的完全限定名对应一个子目录的全路径。
几乎所有Java IDE都采用包和项目机制来管理应用程序的编写和开发。IDE中的包机制为创建和引入包或类提供了方便。下面以Eclipse为例,讨论如何在IDE中设置包。
假设PackageTest.java是项目MyJava的包com.cqcet.java的Java源代码文件。Eclipse提供了多种设置包的方法。列举典型步骤如下所示。
1)创建项目ProjectPackage。选择“File”→“New”→“Java Project”菜单命令,输入项目名“ProjectPackage”,单击“Finish”按钮。
2)在项目名ProjectPackage下,选择“File”→“New”→“Package”菜单命令,在“Name”文本框中输入包名“com.cqcet.java”,单击“Finish”按钮。
3)在包com.cqcet.java下,选择“File”→“New”→“Class”菜单命令,输入类名“PackageTest.java”。注意Eclipse自动在PackageTest.java文件的程序开始处加入com.cqcet.java。
若项目ProjectPackage位于工作区D:\Users\admin\eclipse-workspace,则PackageTest.java文件位于D:\Users\admin\eclipse-workspace\ProjectPackage\src\com\cqcet\java目录下。

3-8 包的导入
3.2.2 包的导入
要使用其他包中的某个类,则必须导入该类所在的包。导入包的语法格式如下。

1)引入整个包时,可以方便地访问包中的每个类。但是引入所有的包会占用过多的内存,因此通常是只引入需要的类。
例如,导入包abc中的单个类ClassName的形式如下。

导入包abc中所有的类和接口的形式如下。

2)程序中不一定要有引入语句。当需要引用的类与当前类在同一个包中,就可以直接使用,而不需要引入。
3)在某些情况下,使用import语句不能正确导入所需要的类。
例如,在程序中导入包java.sql和java.util,代码如下。

如果在程序中使用Date类,则会引发如下编译错误“The type Date is ambiguous”,原因是在包java.sql和包java.util中都有Date类。此时只能在源文件中使用类全名,代码如下。

4)静态导入语句用于导入指定类的静态成员变量或方法,导入某个类的单个静态成员变量或方法的语法格式如下。

导入某个类的全部静态成员变量和方法的语法格式如下。

*号只代表静态成员变量和方法,不包含非静态成员变量和方法。import static语句与import语句的位置相同,这两种语句的功能非常相似,只是导入的对象不一样,它们都用于减少程序中代码的编写量。
这里需要再次强调的是,import语句中的“*”只能代表类,不能代表包。“import abc.*”语句表示导入abc包中所有的类。假设hh是abc包的子包,则hh不会被导入。要导入abc包的子包hh中的所有类,则使用“import abc.hh.*”语句。
【例3-3】 创建包com.cqcet.java,在包中创建类PackageTest1.java和PackageTest2.java两个java文件,在另外一个包中创建主类Example303。

程序运行结果如图3-3所示。

图3-3 例3-3程序运行结果
在主类Example303.java中用“import com.cqcet.java.PackageTest1;”语句导入了包中的类PackageTest1,那么只能用PackageTest1类,而不能用包中的另外一个类PackageTest2。
【例3-4】 在控制台输入圆的半径,求圆的面积。


在程序中导入java.lang包中的System类和Math类的全部静态成员变量和方法,不包含非静态成员变量和方法。其中,in和out是java.lang.System类的静态成员变量,分别代表标准输入和标准输出;PI和pow()是java.lang.Math类的静态成员变量和静态成员方法,程序运行结果如图3-4所示。

图3-4 例3-4程序运行结果
任务实施
创建一个项目Task302,创建car.java包,在此包中定义Bus类和Truck类,创建test.java包,在此包中定义一个Task302类,来测试包car.java的用法。
具体实现步骤如下。
1)启动Eclipse,创建Java项目,项目名称设为“Task302”。
2)在Task302下创建car.java包,并在car.java包下创建Bus.java类。


3)在car.java包下创建Truck.java类。

4)在Task302下创建test.java包,并在test.java包下创建Task302.java类,在Task302类的main()方法里,创建car.java包下的Bus类和Truck类的对象,并调用Bus类和Truck类的方法。

任务演练
【任务描述】
创建项目“项目实训3_2”,创建多个包,并使用多个包中的类。
【任务目的】
1)掌握包的创建方法。
2)掌握包的引用。
【任务内容】
步骤如下。
1)启动Eclipse,创建Java项目,项目名称设为“项目实训3_2”。
2)在项目名“项目实训3_2”下创建包com.cqcet.java1、com.cqcet.java2和test.java。
3)在com.cqcet.java1包下创建类PackageTest1.java和Test.java文件,在com.cqcet.java2包下创建类PackageTest2.java和Test.java文件,在test.java包下创建主类Project302。
4)主类Project302的主方法main()中创建类PackageTest1和PackageTest2的对象,并分别创建com.cqcet.java1包和com.cqcet.java2包的相同类名Test类的对象。
在代码页面上右击,在弹出的快捷菜单中选择“Run As”→“Java Application”命令,运行程序,查看不同包中类的使用方法及不同包中同名的类的使用方法。