为了方便您阅读最新章节,请记住“闪文书库”网址 www.shanwen.com,注册会员收藏您喜爱的书籍
====>>>公告:晚上6点-11点高峰期,可能出现图片打开缓慢,如果太长时间没有打开,请刷新
第二卷第一章
??????
第一章Java语言的产生及其特点
1.1Java产生的历史与现状
1.1.1Java产生的历史
Java来自于Sun公司的一个叫Green的项目,其原先的目的是为家用消费电子产品开发一个分布式代码系统,这样我们可以把E-mail发给电冰箱、电视机等家用电器,对它们进行控制,和它们进行信息交流。开始,准备采用C++,但C++太复杂,安全性差,最后基于C++开发一种新的语言Oak(Java的前身),Oak是一种用于网络的精巧而安全的语言,Sun公司曾依此投标一个交互式电视项目,但结果是被SGI打败。可怜的Oak几乎无家可归,恰巧这时MarkArdreesen开发的Mosaic和Netscape启发了Oak项目组成员,他们用Java编制了HotJava浏览器,得到了Sun公司首席执行官ScottMcNealy的支持,触发了Java进军Internet。Java的取名也有一个趣闻,有一天,几位Java成员组的会员正在讨论给这个新的语言取什么名字,当时他们正在咖啡馆喝着Java(爪哇)咖啡,有一个人灵机一动说就叫Java怎样,得到了其他人的赞赏,于是,Java这个名字就这样传开了。
1.1.2Java的现状
Java是Sun公司推出的新的一代面向对象程序设计语言,特别适合于Internet应用程序开发,它的平台无关性直接威胁到Wintel的垄断地位。一时间,\"连Internet,用Java编程\",成为技术人员的一种时尚。虽然新闻界的报导有些言过其实,但Java作为软件开发的一种革命性的技术,其地位已被确立,这表现在以下几个方面:1.计算机产业的许多大公司购买了Java的许可证,包括IBM,Apple,DEC,Adobe,SiliconGraphics,HP,Oracel,Toshiba,以及最不情愿的Microsoft。这一点说明,Java已得到了工业界的认可。2.众多的软件开发商开始支持Java的软件产品。例如:Borland公司正在开发的基于Java的快速应用程序开发环境Latte,预计产品会在1996年中期发布。Borland公司的这一举措,推动了Java进入PC机软件市场。Sun公司自己的Java开发环境JavaWorkshop已经发布。数据库厂商如:Illustra,Sysbase,Versant,Oracle都在开发CGI接口,支持HTML和Java。今天是以网络为中心的计算时代,不支持HTML和Java,应用程序的应用范围只能限于同质的环境(相同的硬件平台)。3.Intranet正在成为企业信息系统最佳的解决方案,而其中Java将发挥不可替代的作用。Intranet的目的是把Internet用于企业内部的信息系统,它的优点表现在:便宜,易于使用和管理。用户不管使用何种类型的机器和操作系统,界面是统一的Intrnet浏览器,而数据库、Web页面、应用程序(用Java编的Applet)则存在WWW服务器上,无论是开发人员,还是管理人员,抑或是用户都可以受益于该解决方案。Java语言正在不断发展和完善,Sun公司是主要的发展推动者,较通用的编译环境有JDK(JavaDevelopKit)与JWS(JavaWorkshop)。还有很多其他公司正在开发Java语言的编译器与集成环境,预计不久Java语言的正确性与效率都将会提高,用户用Java编程和现在用C++编程一样方便。
1.2Java语言的特点
Java到底是一种什么样的语言呢?Java是一种简单的面象对象的分布式的解释的健壮的安全的结构中立的可移植的性能很优异的多线程的动态的语言。
1.2.1简单
Java最初是为对家用电器进行集成控制而设计的一种语言,因此它必须简单明了。Java语言的简单性主要体现在以下三个方面:1.Java的风格类似于C++,因而C++程序员是非常熟悉的。从某种意义上讲,Java语言是C及C++语言的一个变种,因此,C++程序员可以很快就掌握Java编程技术。2.Java摒弃了C++中容易引发程序错误的地方,如指针和内存管理。3.Java提供了丰富的类库。
1.2.2面向对象
面向对象可以说是Java最重要的特性。Java语言的设计完全是面向对象的,它不支持类似C语言那样的面向过程的程序设计技术。Java支持静态和动态风格的代码继承及重用。单从面向对象的特性来看,Java类似于SmallTalk,但其它特性、尤其是适用于分布式计算环境的特性远远超越了SmallTalk。
1.2.3分布式
Java包括一个支持HTTP和FTP等基于TCP/IP协议的子库。因此,Java应用程序可凭借URL打开并访问网络上的对象,其访问方式与访问本地文件系统几乎完全相同。为分布环境尤其是Internet提?copy;动态内容无疑是一项非常宏伟的任务,但Java的语法特性却使我们很容易地实现这项目标。
1.2.4健壮
Java致力于检查程序在编译和运行时的错误。类型检查帮助检查出许多开发早期出现的错误。Java自已操纵内存减少了内存出错的可能性。Java还实现了真数组,避免了覆盖数据的可能。这项功能特征大大缩短了开发Java应用程序的周期。Java提供Null指针检测数组边界检测异常出口字节代码校验
1.2.5结构中立
另外,为了建立Java作为网络的一个整体,Java将它的程序编译成一种结构中立的中间文件格式。只要有Java运行系统的机器都能执行这种中间代码。现在,Java运行系统有Solaris2.4(SPARC),Win32系统(Windows95和WindowsNT)等.Java源程序被编译成一种高层次的与机器无关的byte-code格式语言,这种语言被设计在虚拟机上运行,由机器相关的运行调试器实现执行。
1.2.6安全
Java的安全性可从两个方面得到保证。一方面,在Java语言里,象指针和释放内存等C++功能被删除,避免了非法内存操作。另一方面,当Java用来创建浏览器时,语言功能和一些浏览器本身提供的功能结合起来,使它更安全。Java语言在你的机器上执行前,要经过很多次的测试。它经过代码校验,检查代码段的格式,检测指针操作,对象操作是否过分以及试图改变一个对象的类型。
1.2.6.1Byte-code校验
如果byte-code通过代码校验,没有返回错误,我们可知道:代码没有堆栈上溢出和下溢出所有操作代码参数类型都是正确的没有发生非法数据转换,如将整数转换成指针。访问对象操作是合法的
1.2.6.2类装载
ClassLoader通过将本机类与网络资源类的名称分开,来保持安全性。因为调入类时总要经过检查,这样避免了特洛伊木马现象的出现。从网络上下载的类被调进一个与源相关的私有的名字域。当一个私有类访问另一个类时,build-in(本机类)首先被检查,然后检查相关的类。这样就避免了破坏本机类情况的出现。
1.2.7可移植的
同体系结构无关的特性使得Java应用程序可以在配备了Java解释器和运行环境的任何计算机系统上运行,这成为Java应用软件便于移植的良好基础。但仅仅如此还不够。如果基本数据类型设计依赖于具体实现,也将为程序的移植带来很大不便。例如在Windows3.1中整数(Integer)为16bits,在Windows95中整数为32bits,在DECAlpha中整数为64bits,在Intel486中为32bits。通过定义独立于平台的基本数据类型及其运算,Java数据得以在任何硬件平台上保持一致。Java语言的基本数据类型及其表示方式如下:byte8-bit二进制补码short16-bit二进制补码int32-bit二进制补码long64-bit二进制补码float32-bitIEEE754浮点数double32-bitIEEE754浮点数char16-bitUnicode字符。
在任何Java解释器中,数据类型都是依据以上标准具体实现的。因为几乎目前使用的所有CPU都能支持以上数据类型、8~64位整数格式的补码运算和单/双精度浮点运算。Java编译器本身就是用Java语言编写的。Java运算系统的编制依据POSIX方便移植的限制,用ANSIC语言写成。Java语言规范中也没有任何\"同具体实现相关\"的内容。
1.2.8解释的
Java解释器(运行系统)能直接运行目标代码指令。链接程序通常比编译程序所需资源少,所以程序员可以在创建源程序上花上更多的时间。
1.2.9高性能
如果解释器速度不慢,Java可以在运行时直接将目标代码翻译成机器指令。Sun用直接解释器一秒钟内可调用300,000个过程。翻译目标代码的速度与C/C++的性能没什么区别。
1.2.10多线程
Java提?copy;的多线程功能使得在一个程序里可同时执行多个小任务。线程--有时也称小进程--是一个大进程里分出来的小的独立的进程。因为Java实现的多线程技术,所以比C和C++更键壮。多线程带来的更大的好处是更好的交互性能和实时控制性能。当然实时控制性能还取决于系统本身(UNIX,Windows,Macintosh等),在开发难易程度和性能上都比单线程要好。任何用过当前浏览器的人,都感觉为调一副图片而等待是一件很烦恼的事情。在Java里,你可用一个单线程来调一副图片,而你可以访问HTML里的其它信息而不必等它。
1.2.11动态
Java的动态特性是其面向对象设计方法的发展。它允许程序动态地装入运行过程中所需要的类,这是C++语言进行面向对象程序设计所无法实现的。在C++程序设计过程中,每当在类中增加一个实例变量或一种成员函数后,引用该类的所有子类都必须重新编译,否则将导致程序崩溃。Java从如下几方面采取措施来解决这个问题。Java编译器不是将对实例变量和成员函数的引用编译为数值引用,而是将符号引用信息在字节码中保存下传递给解释器,再由解释器在完成动态连接类后,将符号引用信息转换为数值偏移量。这样,一个在存储器生成的对象不在编译过程中决定,而是延迟到运行时由解释器确定的。这样,对类中的变量和方法进行更新时就不至于影响现存的代码。解释执行字节码时,这种符号信息的查找和转换过程仅在一个新的名字出现时才进行一次,随后代码便可以全速执行。在运行时确定引用的好处是可以使用已被更新的类,而不必担心会影响原有的代码。如果程序连接了网络中另一系统中的某一类,该类的所有者也可以自由地对该类进行更新,而不会使任何引用该类的程序崩溃。Java还简化了使用一个升级的或全新的协议的方法。如果你的系统运行Java程序时遇到了不知怎样处理的程序,没关系,Java能自动下载你所需要的功能程序。
1.3与C和C++语言的异同
Java提供了一个功能强大语言的所有功能,但几乎没有一点含混特征。C++安全性不好,但C和C++还是被大家所接受,所以Java设计成C++形式,让大家很容易学习。Java去掉了C++语言的许多功能,让Java的语言功能很精炼,并增加了一些很有用的功能,Java去掉了以下几个C和C++功能和特征:指针运算结构typedefs#define需要释放内存全局变量的定义这个功能都是很容易引起错误的地方。
1.4Java的应用简介
1.4.1Web浏览
Web浏览是现在国际网甚至局域网的主要使用方式。文档能很容易地显示文本和各种图片,他还能提供超文本链接。这些浏览器调用HTML语言写的文档,HTML/WWW浏览器技术只限于文本和图象。如果你想播放一种声音或运行一个演示程序,你不得不下载那个文件并用你本机上的能理解和运行那个文件格式的程序来播放它。Java程序和它的浏览器HotJava,提供了可让你的浏览器运行程序的方法。你能从你的浏览器里直接播放声音。你还能播放页面里的动画。Java还能告诉你的浏览器怎样处理新的类型文件。当我们能在2400baud线上传输视频图象时,HotJava将能显示这些视频。
1.4.2网络应用系统
Java是一种与平台无关的语言,因此用Java开发的网络应用系统可以在各种平台上运行,大大增加了开发效率,减少重复劳动。而且,Java集成的网络功能分有利于开发网络应用系统。
本章小结:
1.Java的产生与流行是当今internet发展的客观要求。
2.java是一门各方面性能都很好的编程语言,它的基本特点是简单、面象对象、分布式、解释的、健壮的、安全的、结构中立的、可移植的、性能很优异的、多线程的、动态的。分适合在internet环境上开发应用系统。
3.java可以制作大部分网络应用程序系统,而且与当今流行的WWW浏览器结合得很好。
第二章Java程序开发与运行环境
2.1JDK环境
Java不仅提供了一个丰富的语言和运行环境,而且还提供了一个免费的Java开发工具集(JavaDevelopersKits,简称JDK)。编程人员和最终用户可以利用这些工具来开发java程序或调用Java内容。JDK包括以下工具:javacJava语言编译器,输出结果为Java字节码javaJava字节码解释器javapDisassembeler:Java字节码分解程序,本程序返回Java程序的成员变量及方法等信息。javaprof资源分析工具,用于分析Java程序在运行过程中调用了哪些资源,包括类和方法的调用次数和时间,以及各数据类型的内存使用情况等。javahC代码处理工具,用于从Java类调用C++代码javaAppletViewer小应用程序浏览工具,用于测试并运行Java小应用程序javaDebuggerAPIJava调试工具APIPrototypeDebuggerJava调试工具原型Java开发环境还包括Java类库(包括I/O类库、用户界面类库、网络类库等)和HotJavaWWW浏览器。其中,HotJava浏览器提供了在WWW环境下运行Java代码的一个运行系统,而且还为WWW开发人员提供了一个Java开发框架。Java解释器是面向Java程序的一个独立运行系统,它可以一种稳定、高性能方式运行那些独立于平台的Java字节码,Java编译器则用于生成这些字节码。
2.1.1Java程序的编译
Java程序的编译程序是javac.exe。javac命令将Java程序编译成字节码,然后你可用java解释器java命令来解释执行这些Java字节码。Java程序源码必须存放在后缀为.java的文件里。Java程序里的每一个类,javac都将生成与类相同名称但后缀为.class文件。编译器把.class文件放在.java文件的同一个目录里,除非你用了-d选项。当你引用到某些自己定义的类时,必须指明它们的存放目录,这就需要利用环境变量参数CLASSPATH。环境变量CLASSPATH是由一些被分号隔开的路径名组成。如果传递给javac编译器的源文件里引用到的类定义在本文件和传递的其它文件中找不到,则编译器会按CLASSPATH定义的路径来搜索。例如:CLASSPATH=.;C:\\java\\classes则编译器先搜索当前目录,如果没搜索到,则继续搜索C:\\java\\classes目录。注意,系统总是将系统类的目录缺省地加在CLASSPATH后面,除非你用-classpath选项来编译。javac_g是一个用于调试的未优化的编译器,功能与用法和javac一样。javac的用法如下:javac[-g][-O][-debug][-depend][-nowarn][-verbose][-classpathpath][-nowrite][-ddir]file.java以下是每个选项的解释。
选项解释:-
classpathpath定义javac搜索类的路径。它将覆盖缺省的CLASSPATH环境变量的设置。路径是由一些由逗号隔开的路径名组成,一般格式如下:.;例如:.;C:\\java\\doc\\classes;C:\\tools\\java\\classes表示编译器遇到一个新类,它先在本文件中查找它的定义,如果没有,则在本文件所处目录下其它文件中查找它的定义,如果还没有,则继续搜索C:\\java\\doc\\classes目录中的所有文件,以此类推-
ddirectory指明类层次的根目录,格式如下:javac-dMyProgram.java这样将MyProgram.java程序里的生产的.class文件存放在my_dir目录里-
g带调试信息编译,调试信息包括行号与使用java调试工具时用到的局部变量信息。如果编译没有加上-O优化选项,只包含行号信息-
nowarn关闭警告信息,编译器将不显示任何警告信息-
O优化编译static,final,private函数,注意你的类文件可能更大-
verbose让编译器与解释器显示被编译的源文件名和被加载的类名。
环境变量
CLASSPATH用来提?copy;给系统搜索用户定义的类的缺省路径。各路径由分号隔开,例如:.;C:\\java\\doc\\classes;C:\\tools\\java\\classes表示编译器遇到一个新类,它先在本文件中查找它的定义,如果没有,则在本文件所处目录下其它文件中查找它的定义,如果还没有,则继续搜索C:\\java\\doc\\classes目录中的所有文件,以此类推。
2.1.2Java程序的调试使用java调试器
jdb导游在早期前Betal版的Java调试器jdb是命令行形式的,如用Sun公司的dbx调试器。用jdb来调试Java应用程序,在调试前,要确证你的应用程序是带标志-g编译的。例如:javac-gHelloWorld.javahelp命令将显示jdb里的可用命令列表。
>helpthreads[threadgroup]——列出线程thread--设置缺省线程Suspend[threadsid(s)]--将线程挂起resume[threadid(s)]--重新启动线程where[id]|a1|--打印线程的堆栈threadgroups——列出线程组号threadgroup--设置当前线程组print[id(s)]--打印对象或域dump[id(s)]--打印所有对象信息locals--打印当前堆栈所有局部变量classes--列出当前所知的类methods--列出一个类的成员函数stopin.--在一个成员函数里设置断点stopat:--在一行里设置断点up[nframes]--在线程堆栈里往上移down[nframes]--在线程堆栈里往下移clear:--清除一个断点step--执行当前行cont--从断点处继续执行catch--为指定的情况中断ignor--为指定的情况忽略list[linenumber]--打印源程序use[Sourcefilepath]--显示或改变源路径memeory--报告内存使用情况loadclassname--加载Java类以便调试run--开始执行加载的类!!--重复以上的命令help(?)--列出所有的命令exit(orquit)--离开调试器
2.1.3Java程序的执行
java-java语言解释器java命令解释java字节码语法:java[options]classnamejava_g[options]classname
描述:java命令由java编译器javac输出的Java字节码。classname参数是要执行的类名称。注意任意在类名称后的参数都将传递给要执行类的main函数。java执行完main函数后推出,除非main函数创建了一个或多个线程。如果main函数创建了其它线程,java总是等到最后一个线程推出才推出。
选项:-
cs,-checksource当一个编译过的类调入时,这个选项将比较字节码更改时间与源文件更改时间,如果源文件更改时间靠后,则重新编译此类并调入此新类-
classpathpath定义javac搜索类的路径。它将覆盖缺省的CLASSPATH环境变量的设置。路径是由一?copy;由逗号隔开的路径名组成,一般格式如下:.;例如:.;C:\\java\\doc\\classes;C:\\tools\\java\\classes表示解释器遇到一个新类,它先在本文件中查找它的定义,如果没有,则在本文件所处目录下其它文件中查找它的定义,如果还没有,则继续搜索C:\\java\\doc\\classes目录中的所有文件,以此类推-
mxx设置最大内存分配池,大小为x,x必须大于1000bytes。缺省为16兆-
msx设置垃圾回收堆的大小为x,x必须大于1000bytes。缺省为1兆-
noasyncgc关闭异步垃圾回收功能。此选项打开后,除非显式调用或程序内存溢出,垃圾内存都不回收。本选项不打开时,垃圾回收线程与其它线程异步同时执行-
ssx每个Java线程有两个堆栈,一个是java代码堆栈,一个是C代码堆栈-ss选项将线程理C代码用的堆栈设置成最大为x-
ossx每个Java线程有两个堆栈,一个是java代码堆栈,一个是C代码堆栈-oss选项将线程理java代码用的堆栈设置成最大为x-
v,-verbose让java解释器在每一个类被调入时,在标准输出打印相应信息。
环境变量
CLASSPATH用来提?copy;给系统搜索用户定义的类的缺省路径。各路径由分号隔开,例如:.;C:\\java\\doc\\classes;C:\\tools\\java\\classes表示解释器遇到一个新类,它先在本文件中查找它的定义,如果没有,则在本文件所处目录下其它文件中查找它的定义,如果还没有,则继续搜索C:\\java\\doc\\classes目录中的所有文件,以此类推。
2.2JWS环境
JavaWorkShop是SUN公司的一个新产品,它是一个集成的java语言开发环境,它包括以下工具:lPortfolio和Project管理器l源文件编辑器lBuild管理工具l调试器l项目测试l?copy;展在线超文本连接到帮助文件这?copy;工具在JavaWorkShop的第一页都有类似Web页面的超级连接,如图:注意,JavaWorkShop采用的是当今浏览器的界面风格,你想作什么,只需找到相应的超级连接就可以了,具体编译及调试功能是用嵌如到HTML文档里的Applet实现的,因此,对习惯于用internet浏览方式的用户来说,这种界面很容易接受。
2.2.1Portfolio和Project管理器
Protfolios是一些java应用程序或Applet的集中。它让你更好的管理更多的projects。一个project是portfolio里的一个子集,它包含了以下信息:1.怎样编译本项目2.怎样调试和浏览本项目3.怎样运行本项目4.怎样发布本项目
2.2.2源文件编辑器
源文件编辑器可以从build管理器、调试器和源文件浏览器里的超级连接进入。在这个模块里,你可以输入源文件。
2.2.3Build管理工具
本模块是项目的编译器,你可以点build按钮直接进入本模块,如果某个文件出错,错误信息会提供一个超级连接,直接指到出错的源文件地点。
2.2.4VisulJava(图形界面构造)
顾名思义,本模块能让你可视化建造一个复杂界面,如果你用过VisualBasic,你会发现它们很相似。
2.2.5调试器
调试器能让你很方便地跟踪程序的执行与发现程序的错误。
本章小结:
Java语言有两个开发环境,一个是免费的JDK,是命令行方式的。还有一个JavaWorkShop,是开发java程序的集成环境。本章简要介绍了它们的使用方法。
第三章Java程序设计基础
3.1Java编程概况
现在你可以复习一下Java语言的背景材料,它的基本结构象C/C++,但任何用面向过程语言编写过程序的人都可以了解Java语言的大部分结构.
3.1.1程序结构
Java语言的源程序代码由一个或多个编译单元(compilationunit)组成,每个编译单元只能包含下列内容(空格和注释除外):*一个程序包语句(packagestatement)*入口语句(importstatements)*类的声明(classdeclarations)*界面声明(interfacedeclarations)每个Java的编译单元可包含多个类或界面,但是每个编译单元最多只能有一个类或者界面是公共的。Java的源程序代码被编译?reg;后,便产生了Java字节代码。Java的字节代码由一?copy;不依赖于机器的指令组成,这?copy;指令能被Java的运行系统(runtimesystem)有效地解释。Java的运行系统工作起来如同一台虚拟机。在当前的Java实现中,每个编译单元就是一个以.java为后缀的文件。每个编译单元有若干个类,编译后,每个类生成一个.class文件.class文件是Java虚拟机能够识别的代码。
3.1.2注释
三种类型如下://注释一行/*一行或多行注释*//**文档注释**/文档注释一般放在一个变量或函数定义?reg;前,指示在任何自动生成文档系统中调入。这?copy;注释都是声明条目的描述。
3.1.3标识符
变量,函数,类和对象的名称都是标识符,程序员需要标识和使用的东西都需要标识符。在Java语言里,标识符以字符或_,$开头,后面可以包含数字,标识符是大小写有区别的,没有长度限制。
有效的标识符mynameict_networkHello_sys_path$bill
例子:inta_number;char_onechar;float$bill;
关键词abstractcontinuefornewswitchbooleandefaultgotonullsynchronizedbreakdoifpackagethisbytedoubleimplementsprivatethreadsafebyvalueelseimportprotectedthrowcaseextendsinstanceofpublictransientcatchfalseintreturntruecharfinalinterfaceshorttryclassfinallylongstaticvoidconstfloatnativesuperwhile其它保留词以下单词被保留使用:castfuturegenericinneroperatorouterrestvar
3.1.4数据类型
Java使用五种基本类型:integer(整数),floating(浮点数),point(指针),Boolean(布尔变量),CharacterorString(字符或字符串)。integer整数下边给出的数据表示都是整数的例子:4,15,089,0xAD00整数长度数据类型表示8bitsbyte16bitsshort32bitsint64bitslong
floating浮点数下边给出的数据表示都是浮点数的例子:6.37,3.7E15,3e8
浮点数长度数据类型表示32bitsfloat64bitsdouble
Boolean布尔变量下边是布尔变量的两种可能取值:truefalseCharacter字符下边给出的都是字符的例子:a\\t(tab)\\u????(unicode)
String字符串下边给出的都是字符串的例子:\"Thisisastringliteral\"\"中国科学院计算所\"数组你可以定义任意类型的数组.chars[];这是字符型数组;int[]array;这是整型数组;你还可以定义数组的数组.intblock[][]=newint[2][3];数组边界在运行时被检测,避免堆栈溢出和内存崩溃.
在Java里,数组实际上是一个对象,数组有一个成员变量:length。你可以用这个成员函数来查看任意数组的长度.inta[][]=newint[10][3]a.length/*10*/a[0].length/*3*/创建数组在Java里创建数组,你可使用两种基本方法:一。创建一个空数组:intlist[]=newint[50];或你可以用初始数值填充数组.Stringnames[]={\"Chenji\",\"Yuan\",\"Chun\",\"Yang\"};相当于下面功能:Stringnames[];names=newString[4];names[0]=newString(\"Chenji\");names[1]=newString(\"Yuan\");names[2]=newString(\"Chun\");names[3]=newString(\"Yang\");在编译时你不能象下例那样创建静态数组。intname[50];//将产生一个编译错误你也不能用new操作去填充一个没定义大小的数组。intname[];for(inti=0;ijavaTwoUniversity大学:北?copy;大学城市:北?copy;大学:清华大学城市:北?copy;
5.4点(.?copy;操作符点(.?copy;操作符用来接收一个对象的实例变量和成员函数。下面是用点操作符来接收实例变量的一般形式。objectreference.variablename
这里objectreference是一个对象实例,variablename是这个对象里你想接收的实例变量。下面的程序段说明了怎样用点操作符来给实例变量赋值。
u.name=\"北?copy;大学\";u.city=\"北?copy;\";下面说明怎样用点操作符来得到实例变量的值。System.out.println(\"大学:\"+u.name+\"城市:\"+u.city);通过向类University里加入一个成员函数main,我们创建了一个完整的例子,它使用了new操作符来创建一个University,用点操作符来赋值,然后打印结果。classUniversity{Stringname,city;publicstaticvoidmain(Stringargs[]){Universityu=newUniversity();u.name=\"北?copy;大学\";u.city=\"北?copy;\";System.out.println(\"大学:\"+u.name+\"城市:\"+u.city);}}
运行这个程序后,就会得到下面的结果。C:\\>javaUniversity大学:北?copy;大学城市:北?copy;
5.5成员函数定义
成员函数,是类的功能接口,是类定义里的一个子程序,在类的定义里和实例变量处于同一级别。你必须通过一个类的实例来调用成员函数。成员函数可以不用点操作符而直接使用实例变量。成员函数带有输入参数,具有
某种类型的返回值。成员函数定义的一般形式如下:typemethodname(formal-parameter-list){method-body;}这里type指的是成员函数的返回值的类型,如果没有返回值,就用无值(void?copy;类型。methodname可以是任何合法的标识符,但不能与当前的类名相同。formal-parameter-list是用逗号分隔的类型、标识符对的序列。如果没有参数,括号里就是空的。还是用我们的University的例子,下面的成员函数用来初始化两个实例变量。成员函数是在类的大括号?reg;内定义的,和实例变量所处的范围相同。classUniversity{Stringname,city;voidinit(Stringa,Stringb){name=a;city=b;}}
注意,我们这里直接给name和city赋值,而没有象以前那样用u1.name。这是因为每个成员函数都在类的个别实例内执行。我们创建的类的实例具有它自己的实例变量,所以成员函数可直接使用它们。
5.6成员函数调用
可以用点(.?copy;操作符来调用一个类的实例的成员函数。成员函数调用的一般形式如下:objectreference.methodname(parameter-list);这里,objectreference是指向某个对象的变量,methodname是objectreference所属类的一个成员函数,parameter-list是用逗号分隔的变量或表达式的序列,它们要与该成员函数的定义的参数个数及类型匹配。在这个例子里,我们可以对任何University对象调用成员函数init来给name和city赋值。下面的程序段说明了怎样完成这个工作。Universityu=newUniversity();u.init(\"北?copy;大学\",\"北?copy;\");这个例子创建了University的一个实例,存放在u中。通过点操作符来调用这个实例的init成员函数,把\"北?copy;大学\"和\"北?copy;\"分别传递给参数a和b。在init成员函数内部,name和city直接指向u所指向的对象的实例变量。把name赋值为\"北?copy;大学\",city赋值为\"北?copy;\",然后返回。在这个例子里,init被定义为无值(void?copy;返回类型。在进行这个成员函数调用后,u指向这个name值和city值改变了的University对象。
5.7thisJava有一个特殊的实例值叫this,它用来在一个成员函数内部指向当前的对象。在前面的例子里,我们调用u.init,一?copy;进入init成员函数内部,this就会指向u所指向的对象。在Java里,在同一个范围定义两个相同名字的局部变
量是不可以的。有趣的是,局部变量、成员函数的参数可以和实例变量的名字相同。前面我们没有用name和city作为成员函数init的参数名字,因为这样它们在成员函数的范围里就把实例变量name和city隐藏了,即name指向参数name,隐藏了实例变量name。this让我们可以直接指向对象本身。下面是另一个版本的init,用name和city作为参数名字,用this来接收当前对象的实例变量。
voidinit(Stringname,Stringcity){this.name=name;this.city=city;}下面是带有新的init初始成员函数的TwoUniversity例子。classUniversity{Stringname,city;voidinit(Stringname,Stringcity){this.name=name;this.city=city;}}classTwoUniversityInit{publicstaticvoidmain(Stringargs[]){Universityu1=newUniversity();Universityu2=newUniversity();u1.init(\"北?copy;大学\",\"北?copy;\");u2.init(\"清华大学\",\"北?copy;\");System.out.println(\"大学:\"+u1.name+\"城市:\"+u1.city);system.out.println(\"大学:\"+u2.name+\"城市:\"+u2.city);}}
5.8构造函数(Constructor)
每创建一个类的实例都去初始化它的所有变量是乏味的。如果一个对象在被创建时就完成了所有的初始工作,将是简单的和简洁的。因此,Java在类里提?copy了一个特殊的成员函数,叫做构造函数(Constructor?copy;。一个构造函数是对象被创建时初始对象的成员函数。它具有和它所在的类完全一样的名字。一?copy;定义好一个构造函数,创建对象时就会自动调用它。构造函数没有返回类型,即使是void类型也没有。这是因为一个类的构造函数的返回值的类型就是这个类本身。构造函数的任务是初始一个对象的内部状态,所以用new操作符创建一个实例后,立刻就会得到一个清楚、可用的对象。下面这个例子里,用构造函数取代了成员函数init。
classUniversity{Stringname,city;University(Stringname,Stringcity)
{this.name=name;this.city=city;}}classUniversityCreate{publicstaticvoidmain(Stringargs[]){Universityu=newUniversity(\"北?copy;大学\",\"北?copy;\");System.out.println(\"大学:\"+u.name+\"城市:\"+u.city);}}new语句中类名后的参数是传给构造函数的。
5.9成员函数重载
对于几个意义相近的成员函数,有时使用相同的名字便于理解。因此,Java语言实现了成员函数重载,即可以创建几个名字相同、参数不同的成员函数。成员函数重载提?copy;了Java的多态行为。下面的例子用到了重载。classUniversity{Stringname,city;University(Stringname,Stringcity){this.name=name;this.city=city;}University(){name=\"北?copy;大学\";city=\"北?copy;\";}}
classUniversityCreateAlt{publicstaticvoidmain(Stringargs[]){Universityu=newUniversity();System.out.println(\"大学:\"+u.name+\"城市:\"+u.city);}}
这个例子创建了一个University对象,调用了第二个构造函数。下面是它的运行结果。
C:\\>javaUniversityCreateAlt大学:北?copy;大学城市:北?copy;一个构造函数可以调用另一个构造函数来创建实例。例如:
classUniversity{Stringname,city;University(Stringname,Stringcity)
{this.name=name;this.city=city;}University(){this(\"北?copy;大学\",\"北?copy;\");}}
第二个构造函数调用了第一个构造函数来完成实例的初始化。你也可以用重载来创建一般的成员函数。下面这个例子里有University类的两个版本的samecity成员函数。samecity判断一个大学是否在一个城市里或一个大学和另一个大学是否在同一个城市里。一个成员函数用city作参数,另一个用University对象作参数。
classUniversity{Stringname,city;University(Stringname,Stringcity)
{this.name=name;this.city=city;}booleansamecity(Stringcity){if
(city.equals(this.city))returntrue;elsereturnfalse;}boolean
samecity(Universityu){returnsamecity(u.city);}}
classUniversityCity{publicstaticvoidmain(Stringargs[]){String
city=\"上海\";Universityu1=newUniversity(\"北?copy;大学\",\"
北?copy;\");Universityu2=newUniversity(\"清华大学\",\"北?copy;\");
System.out.println(\"u1=\"+u1.name+\",\"+u1.city);
System.out.println(\"u2=\"+u2.name+\",\"+u2.city);
System.out.println(\"city=\"+city);
System.out.println(\"u1.samecity(u2)=\"+u1.samecity(u2));
System.out.println(\"u1.samecity(city)=\"+u1.samecity(city));}}
下面是该程序的运行结果。
C:\\>javaUniversityCityu1=北?copy;大学,北?copy;u2=清华大学,北?copy;city=上海u1.samecity(u2)=trueu1.samecity(city)=false
5.10继承
第二个基本的面向对象机制是继承。继承是关于有层次关系的类?reg;间的概念。一个类的后代可以继承它的祖先的所有变量和成员函数,就象创建自己的一样。一个类的直接父亲叫做它的超类(superclass?copy;。一?copy;你创建了一个象University这样的类,创建它的子类是很简单的。一个类的子类是它的继承了实例变量和成员函数的特殊的版本。在这个例子里,我们把University类派生为含有叫做country的第三个元素的子类。
classUniversityWorldextendsUniversity{Stringcountry;UniversityWorld(Stringname,Stringcity,Stringcountry){this.name=name;this.city=city;this.country=country;}UniversityWorld(){this(\"北?copy;大学\",\"北?copy;\",\"中国\");}}
关键词extends用来表示我们要创建University的子类。name和city不需再在UniversityWorld中进行声明,因为它们是从University中继承的。Java允许在UniversityWorld中声明变量name和city,但这会隐藏University中的name和city,是与使用子类的目的相矛盾的,应当避免。在UniversityWorld的实例中name、city和country的地位是一样的。
5.11super在UniversityWorld的例子里,有一段代码和它的超类University的重复,这段代码是初始化name和city的,this.name=name;this.city=city;就象在University例子中用this指向第一个构造函数一样,在Java里有另一个变量叫做super,它直接指向超类的构造函数。下面这个例子用super来初始化变量name和city,然后打印出这个对象的内容。
classUniversityWorldextendsUniversity{Stringcountry;UniversityWorld(Stringname,Stringcity,Stringcountry){super(name,city);//调用了构造函数University(name,city)this.country=country;}publicstaticvoidmain(Stringargs[]){UniversityWorldu=newUniversityWorld(\"北?copy;大学\",\"北?copy;\",\"中国\");System.out.println(\"大学:\"+u.name+\"城市:\"+u.city+\"国家:\"+u.country);}}
下面是运行结果。C:\\>javaUniversityWorld大学:北?copy;大学城市:北?copy;国
家:中国
5.12成员函数的覆盖
这个University的新的子类继承了它的超类的成员函数samecity。但这个成员函数samecity判断的是两个城市的名字,这是不够的,因为有可能两个两个名字一样的城市属于不同的国家,我们要用同时判断城市和国家的成员函数来覆盖它。下面就是实现覆盖的例子。
classUniversity{Stringname,city;University(Stringname,Stringcity)
{this.name=name;this.city=city;}booleansamecity(Stringcity){if
(city.equals(this.city))returntrue;elsereturnfalse;}boolean
samecity(Universityu){returnsamecity(u.city);}}
classUniversityWorldextendsUniversity{Stringcountry;
UniversityWorld(Stringname,Stringcity,Stringcountry){super(name,
city);this.country=country;}booleansamecity(Stringcity,String
country){if(city.equals(u.city)&&country.equals(u.country))return
true;elsereturnfalse;}booleansamecity(UniversityWorldother)
{returndistance(other.city,other.country);}}
classUniversityWorldCity{publicstaticvoidmain(Stringargs[])
{Stringcity=\"上海\";Stringcountry=\"中国\";UniversityWorldu1=
newUniversityWorld(\"北?copy;大学\",\"北?copy;\",\"中国\");
UniversityWorldu2=newUniversityWorld(\"清华大学\",\"北?copy;\",\"
中国\");System.out.println(\"u1=\"+u1.name+\",\"+u1.city+\",\"+
u1.country);System.out.println(\"u2=\"+u2.name+\",\"+u2.city+\",
\"+u2.country);System.out.println(\"city=\"+city+\",country=\"+
country);System.out.println(\"u1.samecity(u2)=\"+u1.samecity(u2));
System.out.println(\"u1.samecity(city,country)=\"+u1.samecity(city,
country));}}
下面是输出结果。
C:\\>javaUniversityWorldCityu1=北?copy;大学,北?copy;,中国u2=清华大学,北?copy;,中国city=上海,country=中国u1.samecity(u2)=trueu1.samecity(city,country)=false
5.13动态成员函数发送
为了方便下次访问,请牢记闪文书库网址www.shanwen.com,您的支持是我们最大的动力。注册会员