Java语言程序设计(第3版)
上QQ阅读APP看书,第一时间看更新

4.6 包与类的导入

Java语言使用包来组织类库,包(package)实际是一组相关类或接口的集合。Java类库中的类都是通过包来组织的,用户自己编写的类也可以通过包组织。包实际上提供了类的访问权限和命名管理机制。具体来说,包主要有下面几个作用:

  • 可以将功能相关的类和接口放到一个包中;
  • 通过包实现命名管理机制,不同包中可以有同名的类;
  • 通过包还可以实现对类的访问控制。

4.6.1 包

通常用户自定义的类也应存放到某个包中,这需要在定义类时使用package语句。包在计算机系统中实际上对应于文件系统的目录(文件夹)。

1.package语句

如果在定义类时没有指定类属于哪个包,则该类属于默认包(default package),即当前目录。默认包中的类只能被该包中的类访问。为了有效地管理类,通常在定义类时指定类属于哪个包,这可通过package语句实现。

为了保证自己创建的类不与其他人创建的类冲突,需要将类放入包中,这就需要给包取一个独一无二的名称。为了使用户的包名与别人的包名不同,建议将域名反转过来,然后中间用点(.)号分隔作为包的名称。因为域名是全球唯一的,以这种方式定义的包名也是全球唯一的。

例如,假设一个域名为demo.com,那么创建的包名可以为com.demo。创建的类都存放在这个包下,这些类就不会与任何人的类冲突。为了更好地管理类,还可以在这个包下定义子包(实际上就是子目录),如建立一个存放工具类的tools子包。

要将某个类放到包中,需在定义类时使用package语句指明属于哪个包,如下所示:

上述代码定义了Employee类,代码开头的package语句指明该编译单元中定义的类属于com.demo包。在Java中,一个源文件只能有一条package语句,该语句必须为源文件的第一条非注释语句。

2.如何创建包

上述文件在任何目录中都可以编译,但是编译后的类文件应放在com\demo目录中。由于包名对应于磁盘目录,所以创建包就是创建存放类的目录。创建包通常有两种方法。

1)由IDE创建包

许多IDE工具(如Eclipse或NetBeans等)创建带包的类时自动创建包的路径,并将编译后的类放入指定的包中。

2)使用带–d选项的编译命令

如对于上述源文件可使用下列方法编译:

这里,−d后面指定的路径为包的上一级目录。这样编译器自动在D:\study目录创建一个com\demo子目录,然后将编译后的Employee.class类文件放到该目录中。

将类放入包中后,其他类要使用这些类就可以通过import语句导入。但是,在字符界面下要使编译器找到该类,还需要设置CLASSPATH环境变量。假设原来的CLASSPATH设置为:

修改后的设置应为:

为了方便程序设计和运行,Java类库中的类都是以包的形式组织的,这些类通常称为Java应用编程接口(application programming interface,API)。有关API的详细信息请参阅Java API文档。

3.类的完全限定名

如果一个类属于某个包,可以用类的完全限定名(fully qualified name)来表示。例如,若Employee类属于com.demo包,则该类的完全限定名为com.demo.Employee。

4.6.2 类的导入

为了使用某个包中的类或接口,需要将它们导入到源程序中。在Java语言中使用两种导入:一是使用import语句导入指定包中的类或接口;二是使用import static导入类或接口中的静态成员。

1.import语句

import语句的一般格式为:

选项ClassName指定导入的类名,选用“*”号,表示导入包中所有类。如果一个源程序中要使用某个包中的多个类,用第二种方式比较方便,否则要写多个import语句。导入某个包中所有类并不是将所有的类都加到源文件中,而是使用到哪个类才导入哪个。也可以不用import语句而在使用某个类时指明该类所属的包。

需要注意的是,如果用“*”号这种方式导入的类有同名的类,在使用时应指明类的全名。

程序4.11 PackageDemo.java

该程序在编译时会产生错误。因为在java.util包和java.sql包中都有Date类,编译器不知道创建哪个类的对象,这时需要使用类的完全限定名。如要创建java.util包中的Date类对象,创建对象的语句应该改为:

2.import static语句

从前面的例子可以看到,使用一个类的静态常量或静态方法,需要在常量名前或方法名前加上类名,如Math.PI、Math.random()等。这样如果使用的常量或方法较多,代码就显得冗长。因此在Java 5版中,允许使用import static语句导入类中的常量和静态方法,然后再使用这些类中的常量或方法就不用加类名前缀了。

例如,要使用Math类的random()等方法,就可以先使用下列静态导入语句。

然后在程序中就可以直接使用random()了,请看下面程序。

程序4.12 ImportStaticDemo.java

提示:使用java.lang包和默认包(当前目录)中的类不需要使用import语句将其导入,编译器会自动导入该包中的类。

4.6.3 Java编译单元

一个源程序文件通常称为一个编译单元(compile unit)。每个编译单元可以包含一个package语句、多个import语句以及类、接口和枚举定义。

注意:一个编译单元中最多只能定义一个public类(或接口、枚举等),并且源文件的主文件名与该类的类名相同。