14.3 包
14.3.1 为什么需要包
在生活中,保存文档时会经常使用文件夹,把不同类型的文档归类,然后分放到不同的文件夹中,易于管理和查找,如图 14.7 所示。
易于管理
不同内容的文档可以放在不同的袋子中,拥有相同的名字,避免冲突
文档分门别类,易于查找
在计算机中保存电子文档也不例外。图 14.8 是大家经常看到的 Windows 系统中的树形目录结构。
图 14.7 生活中的文件存储 图 14.8 树形目录结构
在复杂的文件系统中,文件分门别类存储在不同的文件夹中解决了文件同名冲突的问题。事实上,在编写复杂程序的过程中,也会遇到同样的问题。 Java 以类组织程序,开发一个大型的工程可能需要编写成百上千个类。如果要求开发人员确保自己选用的类名不和其他程序员选择的类名冲突,这是很困难的。例如,在程序中,开发人员定义了一个 Sort 类,使用冒泡的方法排序,但另一个人也定义了一个 Sort 类,于是类名冲突,问题就这么产生了, Java 提供包来管理类。类似于文件存储在文件夹中, Java 的类文件可以存储在不同的包中。
包主要有以下三个方面的作用。
(1) 包允许将类组合成较小的单元(类似文件夹),易于找到和使用相应的类文件。
(2) 防止命名冲突: Java 中只有在不同包中的类才能重名。世界上有千千万万的程序员,命名同名的类几乎是难免的。有了包,类名就好管理多了。 A 定义了一个类 Sort, 封装在包 A 中,B 定义了一个类 Sort, 封装在包 B 中。在使用时,为了区别 A 和 B 分别定义的 Sort 类,便可以通过包名区分开,如 A.Sort 和 B.Sort 分别对应于 A 和 B 定义的 Sort 类。
(3) 包允许在更广的范围内保护类、数据和方法,可以在包内定义类。根据规则,包外的代码有可能不能访问该类。
14.3.2 如何声明包
要声明一个包 (package), 只要包含一个 package 命令作为一个 Java 源文件的第一条语句就可以,如示例 6 所示。
示例6
package cn.jbit.classandobject;
public class AccpSchool { public AccpSchool() { } public void showMessage() { System.out.println("这是上海Accp中心。"); } }
在示例 6 中, AccpSchool 类就属于包 cn.jbit.classandobject 。
下面是声明包的通用形式。
语法:
package 包名;
package 是关键字。包的声明必须是 Java 源文件中的第一条非注释性语句,而且一个源文件只能有一个包声明语句。在示例 6 中,使用 package 声明包,包名是 cn.jbit.classandobject 。
Java 中,包被设计与文件系统结构相对应。因此,在命名包时,要严格遵守以下编码规范。
Java 包的名字通常由小写字母组成,不能以圆点开头或结尾。例如, ".mypackage" 是错误的包名。
一个唯一包名的前缀通常是全部小写的 ASCII 字母,并且是一个顶级域名 com 、edu 、gov 、net 或 org, 通常使用组织的网络域名的逆序。例如,如果域名为 javagroup.net, 我们可以声明包为
package net.javagroup.mypackage;
包名的后续部分依不同机构各自内部的规范不同而不同。这类命名规范可能以特定目录名的组成来区分部门、项目、机器或注册名。例如:
package net.javagroup.research.powerproject;
14.3.3 使用 MyEclipse 创建包
问题:使用 Idea 创建 AccpSchool 类,并且使之位于包 cn.jbit.classandobject 中。
分析:在 Idea 中创建包有以下两种方式。
方法一:分别创建包和类。
方法二:在创建类的过程中创建类所属的包。
1. 使用方法一创建包
首先新建一个项目 "项目", 然后选择 "Java模块"点击“next” → "Create project from template" 点击“next”选项。在弹出的 "New Project" 对话框中,在"Preject name"文本框中填写项目名称。在"Preject Location" 文本框中填写项目的存放位置,在"Base package"文本框中填写包名 "cn.jbit.classandobject",如图 14.9 所示。
单击 "Finish" 按钮,在包资源管理器中就能看到图 14.10 所示的效果。
图 14.10 创建包成功的效果 图 14.11 在包中创建类
选择 "cn.jbit.classandobject" 选项,然后新建类 AccpSchool, 在弹出的对话框中填写类名,单击 "Finish" 按钮。大家会在包资源管理器中看到类创建成功的效果,如图 14.11 所示。
14.3.4 包和目录的关系
我们通过创建包来组织程序,在 MyEclipse 中创建包后, Java 源文件是如何存储的呢?
在 Java 中,包被设计与文件系统相对应,事实上, Java 中的每个包都对应于文件系统中同名的子目录。包的嵌套反映了文件系统中的目录层次,如包 cn.jbit.classandobject 对应于文件系统中的cn\jbit\classandobject, 如图 14.14 所示,声明包事实上是在文件系统中创建了相对应的一层层文件夹,而类文件 AccpSchool.java 就存储在最内层文件夹 classandobject 中。
图 14.14 创建包生成的目录结构
下面就来解决一个实际问题。
问题:在 “ PackageTest ” 项目中,在 AccpSchool 类中添加方法 showMessage(), 然后创建 HelloAccp 类,要求该类位于包 “Demo” 中,在 HelloAccp 类中实现 main() 方法调用showMessage( )。
分析:要使用别的包中的类,首先要使用 import 导入这个类。注意:包的声明位于源文件的第一条语句。 import 语句要写在类定义之前,如示例 7 所示。
示例7
AccpSchool 类的实现:
package cn.jbit.classandobject; public class AccpSchool { public AccpSchool() { } public void showMessage() { System.out.println("这是上海Accp中心。"); } }
HelloAccp 类的实现:
package Demo; import cn.jbit.classandobject.AccpSchool; public class HelloAccp { public HelloAccp() { } public static void main(String[] args) { AccpSchool center = new AccpSchool(); center.showMessage(); } }
小结:声明包的含义:声明当前类所处的位置。
导入包的含义:声明在当前类中要使用到的其他类所处的位置。
14.3.6 技能训练
上机练习5
练习——模拟账户查询,实现存取款
需求说明
模拟银行账户业务。
♦创建包 bank. com , 编写 Account 类。
♦添加带参方法,实现存款和取款业务,存款初始为 0 元,取款时需要判断余额是否充足。
♦程序运行结果如图 14.15 所示。
参考代码:
Account类:
package bank.com; /** * 模拟账户查询,实现存取款 * */ public class Account { double money = 0; //初始余额为0元 /** * 查询帐户余额 * @return money 当前余额 */ public double getMoney(){ return money; } /** * 存款 * @param s 存款数目 */ public void save(double s){ money = money + s; System.out .println("存款成功"); System.out .println("\n***当前余额为:"+getMoney()+"元***"); } /** * 取款 * @param a 取款数目 */ public void deposit(double a){ if(money >= a){ money = money - a; System.out .println("取款成功"); System.out .println("\n***当前余额为:"+getMoney()+"元***"); }else{ System.out.println("余额不足!"); System.out .println("\n***当前余额为:"+getMoney()+"元***"); } } }
测试Account类:
package bank.com; /** *模拟账户查询,实现存取款 */ import java.util.*; public class TestAccount { public static void main(String[] args) { Account acc=new Account(); Scanner input = new Scanner(System.in); boolean flag=true;//选择标识 while(flag){ System.out .print("\n1.存款 2.取款 0.退出\n请选择你需要办理的业务:"); int choice=input.nextInt(); if(choice==1){ System.out .print("请输入存款金额:"); double savemoney=input.nextDouble(); acc.save(savemoney); }else if(choice==2){ System.out .print("请输入取款金额:"); double depositmoney=input.nextDouble(); acc.deposit(depositmoney); }else if(choice==0){ flag=false; System.out .print("谢谢使用!"); } else{ System.out .print("选择有误!"); } } } }
本章总结
带参方法定义的一般形式如下。
<访问修饰符> 返回类型 <方法名〉(<参数列表>){ //方法的主体 }
调用带参方法与调用无参方法的语法是相同的,但是在调用带参方法时必须传入实际的参数的值。
形参是在定义方法时对参数的称呼,实参是在调用方法时传递给方法的实际的值。
Java中提供包来管理类。声明包使用关键字package,导入包使用关键字import。