JAVA类和对象的高级特征.docx

上传人:李司机 文档编号:7179816 上传时间:2024-06-29 格式:DOCX 页数:20 大小:29.91KB
返回 下载 相关 举报
JAVA类和对象的高级特征.docx_第1页
第1页 / 共20页
JAVA类和对象的高级特征.docx_第2页
第2页 / 共20页
JAVA类和对象的高级特征.docx_第3页
第3页 / 共20页
JAVA类和对象的高级特征.docx_第4页
第4页 / 共20页
JAVA类和对象的高级特征.docx_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《JAVA类和对象的高级特征.docx》由会员分享,可在线阅读,更多相关《JAVA类和对象的高级特征.docx(20页珍藏版)》请在三一办公上搜索。

1、JAVA类和对象的高级特征(1)第四章JAVA类和对象的高级特征教案名称:教案大小:教案类型:WORD文档星级评定:教案简介:本讲主要讲解并描述了java语言中面对对象的高级特征,包括抽象类、接口和包的特性。通过本讲的学习,同学们可以运用java语言中较为深化的技术编写面对对象程序。下载一1.什么是抽象类、接口?它们各自又有哪些特性?2.你知道java语言在面对对象编程方面有何独特的特点吗?本讲主要讲解并描述了java语言中面对对象的高级特征,包括抽象类、接口和包的特性。通过本讲的学习,同学们可以运用java语言中较为深化的技术编写面对对象程序。应深刻理解各学问点的概念,运用上讲的编程基础学问

2、及面对对象技术,编写各种java类,由浅至深,养成风格良好的编程习惯。1.细致体会面对对象编程的思想,娴熟理解类和对象的概念,理解面对对象的特性,会编写各种java类,渐渐驾驭面对对象编程的方法。2.留意java语言中,不允很多重继承,而运用接口的方法。1.理解方法抽象类和接口,不要混淆了两者的运用。2.接口的运用。4.1抽象类4.2接口4.3包4.4JAVA应用程序编程接口java语言中,用abstract关键字来修饰一个类时,这个类叫做抽象类,用abstract关键字来修饰一个方法时,这个方法叫做抽象方法。格式如下:abstractclassabstractclass抽象类abstract

3、returnTypeabstractMethod(paramlist)/抽象方法抽象类必需被继承,抽象方法必需被重写。抽象方法只需声明,无需实现:抽象类不能被实例化,抽象类不确定要包含抽象方法。若类中包含了抽象方法,则该类必需被定义为抽象类。接口是抽象类的一种,只包含常量和方法的定义,而没有变量和方法的实现,且其方法都是抽象方法。它的用处体现在下面几个方面:通过接口实现不相关类的相同行为,而无需考虑这些类之间的关系。O通过接口指明多个类须要实现的方法。O通过接口了解对象的交互界面,而无需了解对象所对应的类1接口的定义包括接口声明和接口体。接口声明的格式如下:publicinterfaceInt

4、erfaceNameextends1istOfSuperlnterfaceextends子句与类声明的extends子句基本相同,不同的是一个接口可有多个父接口,用逗号隔开,而一个类只能有一个父类。接口体包括常量定义和方法定义常量定义格式为:typeNAME=Value:该常量被实现该接口的多个类共享;具有public,final,static的属性。方法体定义格式为:(具有public和abstract屈性)returnTypemethodName(paramist);2在类的声明中用implements子句来表示一个类运用某个接口,在类体中可以运用接口中定义的常量,而且必需实现接口中定义的

5、全部方法。一个类可以实现多个接口,在implements子句中用逗号分开。3接口作为一种引用类型来运用。任何实现该接口的类的实例都可以存储在该接口类型的变量中,通过这些变量可以访问类所实现的接口中的方法。进行面对对象的设计时,一项基本的考虑是:如何将发生变更的东西与保持不变的东西分隔开。这一点对于库来说是特殊重要的。那个库的用户(客户程序员)必需能依靠自己运用的那一部分,并知道一旦新版本的库出台,Fl己不须要改写代码。而与此相反,库的创建者必需能自由地进行修改与改进,同时保证客户程序员代码不会受到那些变动的影响。为达到这个目的,需遵守确定的约定或规则。例如,库程序员在修改库内的一个类时,必需保

6、证不删除已有的方法,因为那样做会造成客户程序员代码出现断点。然而,相反的状况却是令人苦痣的。对于一个数据成员,库的创建者怎样才能知道哪些数据成员已受到客户程序员的访问呢?若方法属于某个类唯一的一部分,而且并不确定由客户程序员干脆运用,那么这种苦痛的状况同样是真实的。假如库的创建者想删除一种旧有的实施方案,并置入新代码,此时又该怎么办呢?对那些成员进行的任何改动都可能中断客户程序员的代码。所以库创建者处在一个尴尬的境地,好像根本动弹不得。为解决这个问题,Java推出了访问指示符的概念,允许库创建者声明哪些东西是客户程序员可以运用的,哪些是不行运用的。这种访问限制的级别在最大访问和最小访问的范围之

7、间,分别包括:public.友好的(无关键字),protected以及PrivaIeo依据前一段的描述,大家或许已总结出作为一名库设计者,应将全部东西都尽可能保持为private(私有),并只展示出那些想让客户程序员运用的方法。这种思路是完全正确的,尽管它有点儿违反那些用其他语言(特殊是O编程的人的宜觉,那些人习惯于在没有任何限制的状况下访问全部东西。到这一章结束时,大家应当可以深刻体会到Java访问限制的价值。然而,组件库以及限制谁能访问那个库的组件的概念现在仍不是完整的。仍存在这样一个问题:如何将组件绑定到单独一个统一的库单元里。这是通过Java的package(打包)关键字来实现的,而且

8、访问指示符要受到类在相同的包还是在不同的包里的影响。所以在本章的开头,大家首先要学习库组件如何置入包里。这样才能理解访问指示符的完整含义。4.3.1我们用import关键字导入一个完整的库时,就会获得包(PaCkage)。例如:importjava.util.*;它的作用是导入完整的好用工具(Utility)库,该库属于标准Java开发工具包的一部分。由于VCCior位于java.Util里,所以现在要么指定完整名称java.util.Vector(可省略import语句),要么简洁地指定一个VeCtor(因为import是默认的)。若想导入单独一个类,可在import语句里指定那个类的名字:

9、importjava.util.Vector;现在,我们可以臼山地运用VectOFo然而,java.Util中的其他任何类仍是不行运用的。之所以要进行这样的导入,是为了供应一种特殊的机制,以便管理命名空间(NameSpace)。我们全部类成员的名字相互间都会隔离起来。位于类内的一个方法f不会与位于类B内的、拥有相同签名(自变量列表)的f()发生冲突。但类名会不会冲突呢?假设创建一个stack类,将它安装到已有一个StaCk类(由其他人编写)的机器上,这时会出现什么状况呢?对于因特网中的Java应用,这种状况会在用户宅不知晓的时候发生,因为类会在运行一个Java程序的时候自动下载。正是由于存在名

10、字潜在的冲突,所以特殊有必要对Java中的命名空间进行完整的限制,而且须要创建一个完全独一无二的名字,无论因特网存在什么样的限制。迄今为止,本书的大多数例子都仅存在于单个文件中,而且设计成局部(木地)运用,没有同包名发生冲突(在这种状况下,类名置于默认包内)。这是一种有效的做法,而且考虑到问题的简化,本书剩下的部分也将尽可能地采纳它。然而,若安排创建一个对因特网友好或者说适合在因特网运用的程序,必需考虑如何防止类名的重第。为Java创建一个源码文件的时候,它通常叫作一个编辑单元(有时也叫作翻译单元)。每个编译单元都必需有一个以.java结尾的名字。而且在编译单元的内部,可以有一个公共(PUbl

11、iC)类,它必需拥有与文件相同的名字(包拈大小写形式,但解除.java文件扩展名)。假如不这样做,编译器就会报告出错。每个编译单元内都只能有一个public类(同样地,否则编译器会报告出错)。那个编译单元剩下的类(假如有的话)可在那个包外面的世界面前隐减起来,因为它们并非公共的(非public),而且它们由用于主PUbIiC类的支撵类组成。编译一个.java文件时,我们会获得一个名字完全相同的输出文件;但对于java文件中的每个类,它们都有一个.CIaSS扩展名。因此,我们最终从少量的.java文件里有可能获得数量众多的.class文件。如以前用一种汇编语言写过程序,那么可能已习惯编译器先分割

12、出一种过渡形式(通常是一个.Obj文件),再用一个链接器将其与其他东西封装到一起(生成一个可执行文件),或者与一个库封装到一起(生成一个库)O但那并不是Java的工作方式。一个有效的程序就是一系列.class文件,它们可以封装和压缩到一个JAR文件里(运用Java1.1供应的jar工具)。Java说明器负责对这些文件的找寻、装载和说明(注释)。:Java并没有强制确定要运用说明器。一些固有代码的Java编译器可生成单独的可执行文件。库也由一系列类文件构成。每个文件都有一个public类(并没强迫运用一个public类,但这种状况最很典型的),所以每个文件都有一个组件。假如想将全部这些组件(它们

13、在各自独立的.java和.class文件里)都归纳到一起,那么package关键字就可以发挥作用)。若在一个文件的开头运用下述代码:packagemypackage:那么package语句必需作为文件的第一个非注释语句出现。该语句的作用是指出这个编译单元属于名为mypackage的一个库的一部分。或者换句话说,它表明这个编译单元内的public类名位于mypackage这个名字的下面。假如其他人想运用这个名字,要么指出完整的名字,要么与mypackage联合运用import关键字(运用前面给出的选项)。留意依据JaVa包(封装)的约定,名字内的全部字母都应小写,甚至那些中间单词亦要如此。例如,

14、假定文件名是MyClass.java。它意味着在那个文件有一个、而且只能有一个public类。而且那个类的名字必需是MyClass(包括大小写形式):packagemypackage;publicclassMyClass/.现在,假如有人想运用MyClass,或者想运用mypackage内的其他任何public类,他们必需用import关键字激活mypackage内的名字,使它们能够运用。另一个方法则是指定完整的名称:mypackage.MyClassm=newmypackage.MyClassO:import关键字则可将其变得简沾得多:importmypackage.*;/.MyClassm

15、=newMyClassO;作为一名库设计者,确定要记住package和import关键字允许我们做的事情就是分割单个全局命名空间,保证我们不会遇到名字的冲突无论有多少人运用因特网,也无论多少人用Java编写Fl己的类。1创建独一无二的包名大家或许已留意到这样一个事实:由于一个包恒久不会真的封装到单独一个文件里面,它可由多个.ClaSS文件构成,所以局面可能略微有些混乱。为避开这个问题,最合理的一种做法就是将某个特定包运用的全部.ClaSS文件都置入单个书目里。也就是说,我们要利用操作系统的分级文件结构避开出现混乱局面。这正是Java所实行的方法。它同时也解决了另两个问题:创建独一无二的包名以及

16、找出那些可能深藏于书目结构某处的类。正如我们在第2章讲解并描述的那样,为达到这个目的,须要将.ClaSS文件的位置路径编码到PaCkagC的名字里。但依据约定,编译器强迫package名的第一部分是类创建者的因特网域名。由于因特网域名确定是独一无二的(由InterNIC保证注释,它限制着域名的安排),所以假如按这一约定行事,package的名称就确定不会重复,所以恒久不会遇到名称冲突的问题。换句话说,除非将自己的域名转让给其他人,而且对方也依据相同的路径名编写JaVa代码,否则名字的冲突是恒久不会出现的。当然,假如你没有自己的域名,那么必需创建一个特别生僻的包名(例如自己的英文姓名),以便尽最

17、大可能创建一个独一无二的包名。如确定发行自己的JaVa代码,那么剧烈举荐去申请自己的域名,它所需的费用是特别低廉的。:ftp:/这个技巧的另一部分是将package名解析成自己机器上的一个书目。这样一来,JaVa程序运行并须要装载class文件的时候(这是动态进行的,在程序须要创建属于那个类的一个对象,或者首次访问那个类的一个static成员时),它就可以找到class文件驻留的那个书目。Java说明器的工作程序如下:首先,它找到环境变量C1.ASSPATH(将Java或者具有Java说明实力的工具如阅读器安装到机器中时,通过操作系统进行设定)。C1.ASSPATH包含了一个或多个节目,它们作

18、为一种特殊的根运用,从这里绽开对.class文件的搜寻。从那个根起先,说明器会找寻包名,并将每个点号(句点)替换成一个斜杠,从而生成从C1.ASSPATH根起先的一个路径名(所以packagefoo.bar.baz会变成foobarbaz或者foo/bar/baz;详细是正斜杠还是反斜杠由操作系统确定)。随后将它们连接到一起,成为C1.ASSPATH内的各个条目(入口)。以后搜寻.class文件时,就可从这些地方起先查找与打算创建的类名对应的名字。此外,它也会搜寻一些标准节目这些书目与Java说明器驻留的地方有关。为进一步理解这个问题,下而以我臼己的域名为例,它是bruceeckcl.Como

19、将其反转过来后,com.bruceeckel就为我的类创建了独一无二的全局名称(com,cdu,org,net等扩展名以前在JaYa包中都是大写的,但自Java1.2以来,这种状况已发生了变更。现在整个包名都是小写的)。由于确定创建一个名为util的库,我可以进一步地分割它,所以最终得到的包名如下:packagecom.bruceeckel.util;现在,可将这个包名作为下述两个文件的命名空间运用:/:Vector,java/Creatingapackagepackagecom.bruceeckel.util;publicclassVectorpublicVectorOSystem,out.

20、println(com.bruceeckel.util.Vector);/广创建自己的包时,要求package语句必需是文件中的第一个非注释代码。其次个文件表面看起来是类似的:/:1.ist,java/Creatingapackagepackagecom.bruceeckcl.util;publicclass1.istpublic1.istOSystem,out.println(com.bruceeckel.util.1.ist);/广这两个文件都置于我自己系统的一个子书目中:C:DOCJavaTcombruceeckeluti1若通过它往回走,就会发觉包名com.bruceeckel.uti

21、l,但路径的第一部分乂是什么呢?这是由C1.ASSPATH环境变量确定的。在我的机器上,它是:C1.ASSPATH=.;D:JV1.IB:C:DOCJavaT可以看出,C1.ASSPATH里能包含大量备用的搜寻路径。然而,运用JAR文件时要留意一个问题:必需将JAR文件的名字置于类路径里,而不仅仅是它所在的路径。所以对一个名为grape.jar的JAR文件来说,我们的类路径须要包括:C1.ASSPATH=;D:JAVA1.IB;C:flavorsgrape.jar正确设置好类路径后,可将下面这个文件置于任何节目里:/:1.ibTest.java/Usesthe1ibrarypackagec05

22、;importcom.bruceeckel.util.*;publicclass1.ibTest(publicstaticvoidmain(Stringargs)Vectorv=newVectorO;1.ist1=new1.istO;/:编译瑞遇到import语句后,它会搜寻由C1.ASSPATH指定的书目,查找子书目combruceeckelutil,然后查找名称适当的已编译文件(对于VeCtor是VeCtOl.class,对于1.iSt则是1.ist,class)(.留意VeCtOr和1.ist内无论类还是须要的方法都必需设为publico1.Fl动编译为导入的类首次创建一个对象时(或者访

23、问一个类的SlatiC成员时),编译器会在适当的书目里找寻同名的.class文件(所以假如创建类X的一个对象,就应当是X.class)o若只发觉(class,它就是必需运用的那一个类。然而,假如它在相同的书目中还发觉了一个X.java,编译器就会比较两个文件的日期标记。假如X.java比X.class新,就会自动编译X.java,生成一个最新的X.classo对于一个特定的类,或在与它同名的.java文件中没有找到它,就会对那个类实行上述的处理。2.冲突若通过*导入了两个库,而且它们包括相同的名字,这时会出现什么状况呢?例如,假定一个程序运用了下述导入语句:importcom.bruceeck

24、el.util.*;importjava,util.*;由于java,uti1.*也包含了一个Vector类,所以这会造成潜在的冲突。然而,只要冲突并不真的发生,那么就不会产生任何问题这当然是最志向的状况,因为否则的话,就须要进行大量编程工作,防范那些可能可能恒久也不会发生的冲突。如现在试着生成一个VeCtor,就确定会发生冲突。如下所示:VectorV=newVectorO;它引用的究竟是哪个Vector类呢?编译器对这个问题没有.答案,读者也不行能知道。所以编译器会报告一个错误,强迫我们进行明确的说明。例如,假设我想运用标准的JavaVector,那么必需象下面这样编程:java.util

25、.Vectorv=newjava.util.VectorO;由于它(与C1.ASSPTH一起)完整指定了那个Vector的位置,所以不再须要importjava.Util.*语句,除非还想运用来自java.util的其他东西。4.3.2驾驭前述的学问后,接下来就可以起先创建自己的工具库,以便削减或者完全消退重复的代码。例如,可为SyStemoul.prinlln()创建一个别名,削减重熨键入的代码量。它可以是名为tools的一个包(package)的一部分:/:P.java/TheP.rintP.rintlnshorthandpackagecom.bruceeckel.tools;public

26、classP(publicstaticvoidrint(Objectobj)(System,out.print(obj):publicstaticvoidrint(Strings)System.out.print(三);publicstaticvoidrint(chars)System,out.print(三);publicstaticvoidrint(charc)System,out.print(c);publicstaticvoidrint(inti)System,out.print(i);publicstaticvoidrint(long1)System,out.print(l):pub

27、licstaticvoidrint(floatf)System.out.print(f);publicstaticvoidrint(doubled)System,out.print(d);publicstaticvoidrint(booleanb)System,out.print(b):publicstaticvoidrintln()System,out.println();publicstaticvoidrintln(Objectobj)System,out.println(obj):publicstaticvoidrintln(Strings)(System.out.printl11(三)

28、;publicstaticvoidrintln(chars)System,out.println(三):)publicstaticvoidrintln(charc)System,out.println(c):publicstaticvoidrintln(inti)System.out.println(i):publicstaticvoidrintln(long1)System,out.println(l);publicstaticvoidrintln(floatf)System.out.printin(f):publicstaticvoidrintln(doubled)System,out.p

29、rintln(d);publicstaticvoidrintln(booleanb)System.out.println(b):/:全部不同的数据类型现在都可以在一个新行输出(P.rintln(),或者不在一个新行输出(P.rintO)o大家可能会猜想这个文件所在的书目必需从某个C1.ASSPATH位置起先,然后接着com/bruceecke1/tools编译完毕后,利用一个import语句,即可在自己系统的任何地方运用P.class文件。如下所示:ToolTest-Java所以从现在起先,无论什么时候只要做出了一个有用的新工具,就可将其加入tools书目(或者自己的个人Util或toolsH

30、),1.C1.ASSPATH的陷阱P.java文件存在一个特别好玩的陷阱。特殊是对于早期的Java实现方案来说,类路径的正确设定通常都是很困难的一项工作。编写这本书的时候,我引入了P.java文件,它最初看起来好像工作很正常。但在某些状况下,却起先出现中断。在很长的时间里,我都确信这是Java或其他什么在实现时一个错误。但最终,我最终发觉在一个地方引入了一个程序(即第17章要说明的CodePackager.java),它运用了一个不同的类P。由于它作为一个工具运用,所以有时候会进入类路径里;另一些时候则不会这样。但只要它进入类路径,那么假如执行的程序须要找寻com.bruceeckel.too

31、ls中的类,Java首先发觉的就是CodePackagcr.java中的Po此时,编译器会报告一个特定的方法没有找到。这当然是特别令人头疼的,因为我们在前面的类P里明明看到了这个方法,而且根本没有更多的诊断报告可为我们供应一条线索,让我们知道找到的是一个完全不同的类(那甚至不是PUbliC的)。乍一看来,这好像是编译器的一个错误,但假如考察import语句,就会发觉它只是说:在这里可能发觉了Po然行,我们假定的是编译器搜寻自己类路径的任何地方,所以一旦它发觉一个P,就会运用它:若在搜寻过程中发觉了错误的一个,它就会停止搜寻。这与我们在前面表述的略微有些区分,因为存在一些厌烦的类,它们都位于包内

32、。而这里有一个不在包内的P,但仍可在常规的类路径搜寻过程中找到。假如您遇到象这样的状况,请务必保证对于类路径的每个地方,每个名字都仅存在一个类。4.3.3JaVa已取消的一种特性是C的条件编译,它允许我们变更参数,获得不同的行为,同时不变更其他任何代码。Java之所以抛弃了这一特性,可能是由于该特性常常在C里用于解决跨平台问题:代码的不同部分依据详细的平台进行编译,否则不能在特定的平台上运行。由于Java的设计思想是成为一种自动跨平台的语言,所以这种特性是没有必要的。然而,条件编译还有另一些特别有价值的用途。一种很常见的用途就是调试代码。调试特性可在开发过程中运用,但在发行的产品中却无此功能。

33、lenHolubO提出了利用包(PaCkage)来仿照条件编译的概念。依据这一概念,它创建了C断定机制一个特别有用的Java版本。之所以叫作断定机制,是由于我们可以说它应当为真或者它应当为假。假如语句不同意你的断定,就可以发觉相关的状况。这种工具在调试过程中是特殊有用的。可用下面这个类进行程序调试:/:Assert,java/Assertiontoolfordebuggingpackagecom.bruceeckel.tools,debug;publicclassAssertprivatestaticvoidperr(Stringmsg)System,err.printIn(msg);publ

34、icfinalstaticvoidis_true(booleanexp)if(!exp)perr(Assertionfailed);publicfinalstaticvoidis_false(booleanexp)if(exp)perr(Assertionfailed);publicfinalstaticvoidis_true(booleanexp,Stringmsg)if(!exp)perr(Assertionfailed:+msg);publicfinalstaticvoidis_false(booleanexp,Stringmsg)if(exp)perr(Assertionfailed:

35、+msg);)/:这个类只是简洁地封装了布尔测试。假如失败,就显示出出错消息。在第9章,大家还会学习一个更高级的错误限制工具,名为违例限制。但在目前这种状况下,perr()方法已经可以很好地工作。假如想运用这个类,可在自己的程序中加入下面这一行:importcom.bruceeckel.tools,debug.*:如欲清除断定机制,以便自己能发行最终的代码,我们创建了其次个ASSert类,但却是在一个不同的包里:/:Assert,java/Turningofftheassertionoutput/soyoucanshiptheprogram,packagecom.bruceeckel.tool

36、s;publicclassAssertpublicfinalstaticvoidis_true(booleanexp)publicfinalstaticvoidis_fa1se(booleanexp)publicfinalstaticvoidis_true(booleanexp,Stringmsg)publicfinalstaticvoidis_faIse(booleanexp,Stringmsg)/:现在,假如将前一个EPort语句变成下面这个样子:importcom.bruceeckel.tools.*;程序便不再显示出断言。下面是个例子:/:TestAssert.java/Demonst

37、ratingtheassertiontoolpackagec05:/Commentthefollowing,anduncommentthe/subsequentlinetochangeassertionbehavior:importcom.bruceeckel.tools,debug.*;/importcom.bruceeckel.tools.*;publicclassTestAssertpublicstaticvoidmain(Stringargs)Assert.is_true(2+2)=5);Assert.is_false(l+1)=2):Assert.is_true(22)=5,2+2=

38、5):Assert.is_false(l+1)=2,1+1!=2);/:通过变更导入的package,我们可将自己的代码从调试版本变成最终的发行版本。这种技术可应用于任何种类的条件代码。4.3.4大家应留意这样一个问题:每次创建一个包后,都在为包取名时间接地指定了一个书目结构。这个包必需存在(驻留)于由它的名字规定的书目内。而且这个节目必需能从C1.ASSPATH起先搜寻并发觉。最起先的时候,PaCkage关键字的运用可能会令人迷惑,因为除非坚持遵守依据书目路径指定包名的规则,否则就会在运行期获得大量稀里糊涂的消息,指出找不到一个特定的类即使那个类明明就在相同的书目中。若得到象这样的一条消息,

39、请试者将package语句作为注释标记出去。假如这样做行得通,就可知道问题究竟出在哪儿。java中的包:java.apple.Applet小应用程序类java,awt(java,swing)用户界面类java.awt.event事务处理和监听器类java,beans.JavaBeans组件模型类java.io输入输出类jaaIang核心类java.lang,reflect反射机制类java,math随意精度的算术类java,net网络类java,rmi远程方法调用类java,security平安性类java,sqljava数据库连接类java,text国际化文本处理类java,util各种好用工具类

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号