1、第7章 Java接口、包和异常,7.1 接口7.1.1 接口概述 在Java中,出于简化程序结构的考虑,不再支持类间的多重继承而只支持单继承,即一个类至多只能有一个直接父类。然而在解决实际问题的过程中,仅仅依靠单继承在很多情况下都不能将问题的复杂性表述完整,需要其他的机制作为辅助。 接口的主要作用就是帮助实现类似于类间多重继承的功能。接口定义了一组没有实现的抽象方法,方法的真正实现在实现接口的类中完成。,7.1 接 口,7.1.2 接口的定义 接口定义的一般形式如下: 修饰符 interface 接口名 extends 父接口列表 抽象方法声明 成员变量声明 从上面的语法规定可以看出,定义接口
2、与定义类非常相似,实际上可以把接口理解成为一种特殊的抽象类。 接口的特殊性体现在:(1)接口由常量和抽象方法组成。(2)一个类只有一个父类,而一个接口可获得多个父类,可实现多重继承。,7.1 接 口,接口的特点:(1)和类的访问级别类似,接口的访问权限要么是public,要么采用默认访问。(2)接口中的所有方法都是抽象方法,在接口中只能给出这些抽象方法的方法名、返回值类型和参数列表,没有方法体。(3)接口中定义的成员变量都是final和static型的,这意味着这些成员变量的值不能通过实现类而改变,并且必须以常量值初始化。(4)接口中的方法不声明的默认为public abstract;接口中的
3、成员变量不声明的默认为public static final 。(5)接口不是类,所有接口中不能定义构造方法。,7.1 接 口,7.1.3 实现接口的类定义 一旦接口被定义,一个或多个类可以实现该接口。为了实现一个接口,在类定义中使用implements关键字。其一般形式如下: 修饰符 class 类名 extends 父类名 implements 接口列表 成员变量声明 成员方法声明 ,7.1 接 口,实现接口的说明:(1)一个类可以实现多个接口,这些接口被逗号分隔。(2)如果实现某接口的类不是抽象类,则在类的定义部分必须实现指定接口的所有抽象方法。(3)如果实现某接口的类是抽象类,则它可以
4、不实现该接口中所有的抽象方法。但是对于这个抽象类的任何一个非抽象子类而言,它们父类所实现的接口中的所有抽象方法都必须有实在的方法体。(4)接口的抽象方法的访问控制符被指定为public,所以类在实现方法时,必须显式使用public修饰符。而且,实现方法的类型必须严格与接口定义中指定的类型相匹配。【例7.1】接口定义和实现接口的类定义。【例7.2】实现多接口的类定义。,7.2 包,Java语言中的包(package)是类和接口的集合,它从更高级别上提供了对类和接口的存取保护和命名空间管理。 通常把需要在一起工作的类放在一个包里。包是一种松散的类的集合,一般不要求处于同一个包中的类有明确的相互关系
5、(包含、继承等)。 包的出现也减少了命名上的冲突,这样类和接口的名字只要在它们所在包内没有冲突就可以了。,7.2 包,7.2.1 创建包 创建一个包是很简单的:只要包含一个package命令作为一个Java源文件的第一句就可以了。该文件中定义的任何类将属于指定的包。如果省略package语句,该文件中定义的任何类将属于一个默认的无名包。 package语句的一般形式为: package 包名称; 例如:package mypackage; 我们也可以创建包层次,只要将包名与它的上层包名用点号“.”分隔开就可以了。其通用形式为: package pkg1.pkg2.pkg3;例如:package
6、 chapter5.example3;,7.2 包,创建包的注意事项如下:(1)程序中如果有package语句,该语句一定是源文件中的第一条可执行语句,它的前面只能有注释和空行。一个文件中最多只能有一条package语句。(2)在Java语言中可以出现在类定义括号外面的仅有两个语句,它们是package和import。 包的层次结构 Java用文件系统目录来存储包,目录名称必须和包名严格匹配。例如:任何声明为mypackage包中的类的.class文件必须被存储在一个mypackage目录中。 包层次必须与Java开发系统的文件系统结构相同。例如,如果源文件中声明如下: package cha
7、pter5.example3;则相对应的.class文件必须存放在chapter5example3目录下。,7.2 包,【例7.4】将Timer1类放入c:j2sdk1.4.1-02jreclasses的com.juj包中。 注意有package语句的源文件的编译方法: javac d c:j2sdk1.4.1_02jreclasses Time1.java 不带-d参数编译没有package语句的源文件,生成的.class文件存放在当前工作目录中,称无名包。,7.2 包,7.2.2 类的包外引用在 Java中,如果一个类已经被保存在某一个包中,则必须通过列举包层次来引用该类。也就是说,完整的
8、类名必须包括该类所属的包名。例如,如果chapter5.example3包中已经包含了Polymorphism类,则该类的完整类名是: chapter5.example3.Polymorphism 为了使类的引用更为简单,可以使用import语句来引入特定的类甚至是整个包。一旦被引入,类可以被直呼其名的引用,包名可省略。在Java源文件中,import语句紧接着package语句,存在于任何类定义之前。其通用形式为: import pkg1.pkg2n.classname|*;例如: import java.applet.Applet; /引入java.applet包中的Applet类 imp
9、ort java.awt.*; /引入java.awt整个包,7.2 包,使用import语句需要注意的事项:(1)引入整个包意味着可以方便地访问包中的任何一个类或接口,但这样做会占用过多的内存空间,延长编译时间。因此,明确的引入需要使用的类而不是引入整个包是一个好的方法。(2)包在命名上遵循的是一种层次结构,但import声明却不是。例如,“import java.awt.*;”只能引入java.awt包中的类和接口,而不包括其子包中的类和接口。所以如果需要,我们还必须使用另一个单独的import声明。例如: import java.awt.image.*; import java.awt.
10、event.*;【例7.5】包的编译与运行实例1。,7.2 包,Java 包 java.lang包:包括了所有支持Java语言和Java虚拟机运行的最基本的类和接口,为保证这些类和接口可以被方便地使用,系统总是将java.lang包自动地引入到每个源程序文件中。也就是说,在程序开头写不写下面一行代码是一样的: import java.lang.*; java.io包:标准输入、输出类库。 java.awt包:图形用户界面类库。 java.applet包:在浏览器中运行java applet的工具类库。 包:实现网络功能类库。 java.sql包:实现数据库连接的类库。,7.3 异常处理,7.3
11、.1 异常的基本概念 异常 (Exception)是指应用程序在运行过程中发生的不正常情况,或发生错误(Error)。 无论是错误还是异常,编程人员关心的是出现这些情况后应如何处理。传统的面向过程编程语言中,出现处理的任务几乎完全由编程人员来承担,造成编程人员负担过重,出错处理不规范。而在Java中,通过异常处理机制进行处理。,7.3 异常处理,Java的异常处理机制: Java中定义了很多异常类,每个异常类代表了一种运行错误,类中包含了该运行错误的信息和处理错误的方法等内容。每当Java程序运行过程中发生一个可识别的运行错误时,即该错误有一个异常类与之相对应时,系统都会产生一个相应的该异常类
12、的对象,即产生一个异常。一旦一个异常对象产生了,系统中就有相应的机制来处理它,确保不会产生死机、死循环或其他对操作系统的损害,从而保证整个程序运行的安全性。,7.3 异常处理,异常类的层次,7.3 异常处理,Throwable类用来表示所有的异常情况,每个异常类型都是Throwable的子类。Throwable派生出两个直接的子类:Error和Exception。 Error类表示很难恢复的严重错误,如系统内部错误和资源耗尽错误等。用户程序不应抛出这种类型的错误,而是交给系统处理为好。 Exception类表示用户程序能够捕捉到的异常情况,分为IOExceptiop、RuntimeExcept
13、ion类的异常和Non_RuntimeException类的异常。这时,用户可以编写代码来处理异常并继续程序的执行。,7.3 异常处理,Exception类异常的分类:(1)不受检异常 由编程错误产生的异常,如被零除、数组越界访问、数组大小为负数等。这类错误数量较大,通常应用程序不需要对不受检异常对象进行监视,可以通过Java编译器的检查。程序运行时,如产生这类异常,JVM将捕捉异常对象,并交默认的异常处理程序,在标准输出上显示异常信息,终止程序向下执行。【例7.7】不受检异常的例子。,7.3 异常处理,(2)受检异常 是由于意外情况而发生的异常,如试图读取文件结尾以后的数据、试图打开错误的U
14、RL、试图根据并不代表已存在类的字符串来查找Class对象等。 Java规定:在编写输入/输出、网络通信和数据库访问的方法程序时,是受编译器检查的,必须使用throws子句或在方法中使用try-catch结构,进行异常对象的捕捉和处理。【例7.9】受检异常的例子。,7.3 异常处理,7.3.2 异常处理机制1. 程序内部处理和try-catch结构 为了防止和处理程序运行时出现的异常情况,只需要使用try语句括住可能抛出异常的代码段,用catch语句指明要捕获的异常及相应的处理代码。其语法格式如下:,7.3 异常处理,try 可能抛出异常的程序代码catch(异常类名1 异常对象名1) 异常类
15、1对应的的处理代码catch(异常类名2 异常对象名2) 异常类2对应的的处理代码 finally 必须执行的代码 ,7.3 异常处理,说明:(1)将可能发生异常的程序代码放置在try程序块中。如果该块内的代码没有出现异常,后面的catch块不起作用;如果该块内的代码出现了异常,系统的异常处理机制会自动捕捉到它,并终止try块代码的执行,自动跳转到所发生的异常类对应的catch块中,执行该块的代码。(2)一个try块可以对应多个catch块。(3)finally块是可选项。如果包含该块,无论异常出现与否,其中的代码必定执行。【例7.8】用try-catch结构检测、处理不受检异常。【例7.10
16、】一个不受检异常程序内部处理的例子。,7.3 异常处理,2. 抛出异常外部处理和throws子句格式:方法说明 throws 异常类列表功能:告诉编译器该方法可能会产生哪些异常,从而要求它的调用者必须考虑处理这些异常。说明:(1)throws后指明的必须是可能发生的要检查的异常,对Java不检查的异常(Error类派生的异常、RuntimeException类派生的异常)不需指定。 (2)为了明确指出一个方法不捕获某类异常,而让调用该方法的其他方法捕获该类异常,可在声明方法时,使用throws选项抛出该类异常。【例7.11】一个受检异常外部处理的例子。【例7.12】一个受检异常内部处理的例子。
17、,7.3 异常处理,3. 程序内部处理和外部处理两者结合和throw语句抛出异常语句:throw new 异常类名 (信息); 其中:异常类为系统异常类名或用户自定义的异常类名。 说明:含有throw语句的方法,应该在方法头定义中增加: throws 异常类名列表 目的:让调用此方法的方法,由于该方法中包含有throw语句,所以要准备接受和处理它在运行过程中可能抛出的异常。7.3.3 自定义异常 Java类库中定义的异常类主要处理可以预见、常见的运行错误,对系统不能识别的异常,我们可以创建自己的异常类,以便对特殊的异常进行处理。 创建的方法很简单:继承已有的异常类。 class 自定义异常类名 extends Exception 异常类体; 【例7.13】自定义异常实例。,