第6章包、接口和异常主要任务介绍Java中包(package)、接口(interface)和异常处理(exception)的使用方法。本章主要内容1.包2.接口3.异常处理6.1包Java要求文件名与类名相同,将多个类放在一起时,要保证类名不能重复。当声明的类很多时,类名就有可能冲突,这就需要一种机制来管理类名,这就是包。包是Java提供的一种区别类名空间的机制,是类的组织方式,一个包对应一个文件夹,包中还可以有包,称为包等级。如同文件夹中可以有子文件夹。在源程序中可以声明类所在的包,就像保存文件时要说明文件保存在哪个文件夹中一样。同一个包中类名不能重复,不同包中可以有相同的类名。当源程序中没有声明类所在的包时,Java将类放在默认包中,即运行编译器的当前文件夹中。这时,不能出现重复的类名。6.1.1Java的系统包Java提供了大量的类,为便于管理和使用,分为不同的包。包又称类库或API包,所谓API(ApplicationProgramInterface)即应用程序接口。API包—方面提供丰富的类与方法供大家使用,如画图形、播放声音等,另一方面又负责和系统软硬件打交道,把用户程序的功能圆满实现。所有JavaAPI包都以“java.”开头,以区别用户创建的包。1.java.lang包java.lang包中包含有以下的主要类:·数据类型包装类,对应8个基本数据类型,数据类型包装类也有8个:BigDecimal、BigInteger、Byte、Double、Float、Integer、Long、Short。·提供基本数学函数的Math数学类。·用于字符串处理的String类和StringBuffer类。·System系统类。提供访问系统资源和标准输入输出的方法。·Object类。它是Java类层次的根,所有其它的类都是由Object类派生出来的。2.java.util包包含一些低级的实用工具类。这些实用工具类使用方便,而且很重要。主要有:日期Date类、堆栈Stack类、随机数Random类、向量Vector类等。3.java.io包是Java语言的输入输出类库,Java语言的文件操作都是由该类库中的输入输出类来实现的。此外该类库还提供了一些与其它外部设备交换信息的类。java.io包除了包含标准输入、输出类外,还有缓存流、过滤流、管道流和字符串类等。4.java.net包含有访问网上资源的URL类,用于通讯的Sockt类和网络协议子类库等。Java语言是一门适合分布式计算环境的程序设计语言,网络类库正是为此设计的。其核心就是对Internet协议的支持,目前该类库支持多种Internet协议,包括HTTP、Telnet、FTP等等。5.java.awt包提供了创建图形用户界面的全部工具。它包括许多我们熟悉的图形组件(component)类,如窗口、对话框、按钮、复选框、列表、菜单、滚动条和文本区等类;用于管理组件排列的布局管理器Layout类;以及常用的颜色Color类、字体Font类。java.awt.event类库用来处理各种不同类型的事件。6.java.applet包java.applet是所有小应用程序的基础类库。它只包含了一个Applet类,所有小应用程序都是从该类中派生的。7.java.security包包括java.security.acl和java.security.interfaces子类库,利用这些类可对Java程序进行加密,设定相应的安全权限等。Java提供的最新内容,如图所示。object类的所有方法和构造方法,如图所示。6.1.2包的引用1.导入包语句在Java程序中是怎样告诉编译器使用哪些包中的类呢?在编写源程序时,如果要使用某个包中的类,要在Java程序的开头添加import语句,指明源程序要使用含有该类的包。如下面的语句:importjava.awt.Graphics;importjava.applet.*;2.包的路径要引入Java包,仅在程序中添加import语句还不够,还要告诉系统,程序运行时到哪里去找Java包。这个功能由环境变量classpath来完成。由于Java使用文件系统来存储包和类,类名就是文件名,包名就是文件夹名,所以进行环境变量的设置就是找到存放包的路径,如“E:\j2sdk1.4.2_01\lib;”。6.1.3创建自定义包1.自定义包的声明方式要建立自定义包,要使用声明包语句。格式为:package自定义包名声明包语句必须添加在源程序的第一行,表示该文件的全部类都属于这个包。开发人员还可以在不同的文件中使用相同的声明包语句,这样就可将不同文件中的类都包含在相同的包中了,如同将不同的文件放在同一个文件夹中,以后其它类就可以引用这个包中创建好的类了。例6.1在源程序YMD.java中,创建了YMD类,该类具有计算今年的年份,可以输出一个带有年月日的字符串的功能。packageMypackage;//声明了一个Mypackage包importjava.util.*;//引用java.util包publicclassYMD{privateintyear,month,day;publicstaticvoidmain(String[]arg3){}publicYMD(inty,intm,intd){year=y;month=(((m=1)&(m=12))?m:1);day=(((d=1)&(d=31))?d:1);}publicYMD(){this(0,0,0);}publicstaticintthisyear(){returnCalendar.getInstance().get(Calendar.YEAR);//获得当年的年份}publicintyear(){returnyear;//获得年份}publicStringtoString(){returnyear+-+month+-+day;//转化为字符串}}例6.2本程序中,引用了例6.1创建的放入Mypackage包中的YMD类,使用YMD类类中的方法和P3类中的方法,给定某人的出生日期计算出该人年龄,并输出该人姓名,年龄,出生日期。importMypackage.YMD;//引用Mypackage包中的YMD类publicclassP3{privateStringname;privateYMDbirth;publicstaticvoidmain(Stringargs[]){P3a=newP3(张驰,1990,1,11);a.output();}publicP3(Stringn1,YMDd1){name=n1;birth=d1;}publicP3(Stringn1,inty,intm,intd){this(n1,newYMD(y,m,d));//初始化变量与对象}publicintage(){returnYMD.thisyear()-birth.year();//计算年龄}publicvoidoutput(){System.out.println(姓名:+name);System.out.println(出生日期:+birth.toString());System.out.println(今年年龄:+age());}}程序运行结果如图所示。第一个程序声明了自定义包Mypackage,包中存放有YMD类。第二个程序引入了自定义包Mypackage中的类YMD。2.设置包的路径首先在存放源程序的文件夹中使用自定义包名建立一个子文件夹,例如,在“E:\java\程序”文件夹之中创建一个与包同名的文件夹E:\java\程序\Mypackage,并将编译过的class文件放入该文件夹中。注意:包名与文件夹名大小写要一致。再添加环境变量classpath的路径如下:E:\j2sdk1.4.2_01\lib;E:\java\程序3.创建包等级用圆点“.”可以将包名分隔为不同的包等级,即建立不同的文件夹。格式为:package包名1[.包名2][.包名3}如java.awt.image就是一个等级包,反映Java开发系统的层次关系,这个包对应Windows文件系统中的java\awt\image文件夹。如果要修改包名就要修改文件夹名。6.2接口什么是接口?所谓接口可以看作是没有实现的方法和常量的集合。接口与抽象类相似,接口中的方法只是做了声明,而没有定义任何具体的操作方法。使用接口是为了解决Java语言中不支持多重继承的问题。6.2.1实现系统提供的接口Java已经创建了许多系统接口,如MouseListener和MouseMotionListener接口,定义了处理鼠标事件的方法,当一个类实现这两个接口后,就可以处理这些鼠标事件。在接口中的方法只有定义没有实现。在接口中定义的变量全部隐含为final和static,表明这些变量不能被实现接口方法的类改变,这些变量还必须设置初值。如果接口为public的,则接口中的方法和变量也全部为public,否则只能被处于同一包中的成员访问。例6.3在类中实现MouseListener和MouseMotionListener两个接口。importjava.applet.Applet;importjava.awt.*;importjava.awt.event.*;publicclassDrawLextendsAppletimplementsMouseListener,MouseMotionListener{intx1,y1,x2,y2;publicvoidinit(){addMouseListener(this);addMouseMotionListener(this);}publicvoidpaint(Graphicsg){g.drawL(x1,y1,x2,y2);}publicvoidmousePressed(MouseEvente){//记录起点坐标x1=e.getX();y1=e.getY();}publicvoidmouseClicked(MouseEvente){}publicvoidmouseEntered(MouseEvente){}publicvoidmouseExited(MouseEvente){}publicvoidmouseReleased(MouseEvente){}publicvoidmouseDragged(MouseEvente){//记录终点坐标x2=e.getX();y2=e.getY();repaint();}publicvoidmouseMoved(MouseEvente){}}在DrawL类中实现了MouseListener接口中定义的5个方法:publicvoidmousePressed(MouseEvente){//记录起点坐标x1=e.getX();y1=e.getY();}publicvoidmouseClicked(MouseEvente){}publicvoidmouseEntered(MouseEvente){}publicvoidmouseExited(MouseEvente){}publicvoidmouseReleased(MouseEvente){}实现MouseMotionListener接口的两个方法:publicvoidmouseDragged(MouseEvente){//记录终点坐标x2=e.getX();y2=e.getY();repaint();}publicvoidmouseMoved(MouseEvente){}6.2.2创建自定义接口创建自定义接口要使用声明接口语句,格式如下:[修饰符]interface自定义接口名{…//静态常量及方法声明}例6.4_1在下面的程序中声明了一个自定义接口Nl。用来计算一个人年龄interfaceNl{//年龄接口intyear=2003;intage();voidoutput();