1第5章接口和包本章主要讲述如下内容:接口的定义和使用;接口与抽象类的异同点;包的定义和使用;25.1接口•引入接口的原因:在程序设计中经常遇到这样一个问题:有些类互不相关,但却具有相似的方法。并且这些方法在各个类中的实现互不相同。我们不能为这些类定义一个共同的父类,但又希望在程序中体现出它们共同的接口。35.1.1接口的定义和应用•接口是一系列常量和空方法的集合,它提供了多个类共同的方法,但不限制每个类如何实现这些方法。•Java允许一个类同时实现多个接口,相当于实现多继承的功能。45.1.1接口的定义和应用(续)•声明一个接口的语法格式:[public]interfaceinterfaceName[extendssuper-interface-List]{typeConstantName=value;typeMethodName(Parameterlists);}55.1.1接口的定义和应用(续)•接口中不能声明任何变量和构造函数。•如果一个类实现多个接口,应该在接口名之间用逗号隔开。•当一个类实现接口时,必须实现接口中给出的空方法,若实现接口的类是一个抽象类,可以把实现接口的任务交给子类去实现。例如://程序5-1interfaceSortable{//定义一个接口intCompare(Sortables);}classSort{//定义一个排序类,仅有一个静态的方法publicstaticvoidSelectSort(Sortablea[]){inti,j,k;Sortabletemp;for(i=0;ia.length-1;i++){//选择排序k=i;for(j=i+1;ja.length;j++)if(a[k].Compare(a[j])0)k=j;temp=a[i];a[i]=a[k];a[k]=temp;}}}classStudentimplementsSortable{//定义一个学生类privateintscore;Student(intx){score=x;}//实现接口Sortable中的方法publicintCompare(Sortables){Studentst=(Student)s;//类型强制转换returnscore-st.score;}publicStringtoString(){returnscore=+score;}}classRectangleimplementsSortable{//矩形类也实现了接口privateintlength,width;Rectangle(intx,inty){length=x;width=y;}intarea(){returnlength*width;}publicintCompare(Sortables){//实现接口Rectanglerec=(Rectangle)s;//类型强制转换returnarea()-rec.area();}publicStringtoString(){returnarea=+area();}}publicclassinterfaceTest{publicstaticvoidmain(Stringargs[]){Studentstud[]=newStudent[20];inti;for(i=0;istud.length;i++)stud[i]=newStudent((int)(Math.random()*100));Sort.SelectSort(stud);//排序for(i=0;istud.length;i++)System.out.println(stud[i].toString());RectangleR[]=newRectangle[10];for(i=0;iR.length;i++)R[i]=newRectangle((int)(Math.random()*10),(int)(Math.random()*10));Sort.SelectSort(R);//排序for(i=0;iR.length;i++)System.out.println(R[i].toString());}}125.1.1接口的定义和应用(续)•接口中定义的变量实际上是常量,必须给出它们的初始值,实现接口的类可以自由引用这些常量。例如://程序5-2的部分interfaceconstant{intEXCELLENT=5;intGOOD=4;intPASS=3;intFAIL=2;}135.1.1接口的定义和应用(续)•在类中实现接口中方法时,方法的特征必须和接口中声明的方法特征保持一致;•实现方法时必须在方法前加上public;•若一个类没有对接口中的方法具体实现,那么必须将该类声明为abstract类。例如:interfaceinter{//接口voidmethodA();}abstractclassDerived1implementsinter{//此处不需要写出methodA()的原型}classDerived2extendsDerived1{publicvoidmethodA(){//实现方法System.out.println(Hi,methodA);}}155.1.2接口和抽象类的异同点•接口和抽象类的相同点:(1)都有空的方法,都必须在子类中实现这些方法。(2)都不能用new关键字来创建这两种类型的对象。(3)都可以具有继承关系。(4)接口和类一样可以具有public属性。165.1.2接口和抽象类的异同点(续)•接口和抽象类的不同点:(1)在抽象类中,空的方法必须加abstract关键字,而在接口中不需要。(2)在抽象类中,除空的方法外,可以定义实例变量和非空的方法,而在接口中,只能定义常量和空的方法。(3)接口允许多继承,类仅支持单继承。175.2包•在Java中可以将自己写的类,按一定的方法归属于不同的子目录中(包)。•在缺省情况下,Java将所有的类归属一个缺省包中。在不同的包中可以有同名的类存在。•Java中的包与C++中的名字空间相似。185.2.1package语句•package语句告诉编译器当前类属于哪个包。如果没有package语句,类就存放在无名的缺省包中(即当前目录中)。•引进包的概念主要是为了名字冲突。•格式:packagepkgl[.pkg2[.pkg3]];195.2.2import语句•import语句位于package语句之后,类的定义之前;•格式:importpackage1[.package2].(class-name|*);•采用*号不影响程序的运行性能,但会影响编译速度。指明具体类比引入整个包更为合理。205.2.3包应用举例packageBase;//将该类存放在d:\myjava\Base包中publicclassBase{intfriend_data=1;//友元成员publicintpublic_data=2;//public成员privateintprivate_data=3;//private成员protectedintprotected_data=4;//protected成员}packageDerived;//将Base类存放在Derived包中importBase.*;//需要使用Base包中的类publicclassDerivedextendsBase{Basea=newBase();//为了让testData类能调用该方法,修改为publicpublicvoiddataUse(){//System.out.println(a.friend_data);//不能访问System.out.println(a.public_data);//System.out.println(a.private_data);//不能访问//System.out.println(a.protected_data);//不能访问}}//testData.java文件的内容如下:importDerived.*;//需要使用Derived包中的类//该类位于工作目录,不需要package语句publicclasstestData{publicstaticvoidmain(Stringargs[]){Derivedd=newDerived();d.dataUse();}}23思考和练习•P983~6