电子教案-Java程序设计项目教程课件

上传人:博****1 文档编号:567698251 上传时间:2024-07-22 格式:PPT 页数:457 大小:2.84MB
返回 下载 相关 举报
电子教案-Java程序设计项目教程课件_第1页
第1页 / 共457页
电子教案-Java程序设计项目教程课件_第2页
第2页 / 共457页
电子教案-Java程序设计项目教程课件_第3页
第3页 / 共457页
电子教案-Java程序设计项目教程课件_第4页
第4页 / 共457页
电子教案-Java程序设计项目教程课件_第5页
第5页 / 共457页
点击查看更多>>
资源描述

《电子教案-Java程序设计项目教程课件》由会员分享,可在线阅读,更多相关《电子教案-Java程序设计项目教程课件(457页珍藏版)》请在金锄头文库上搜索。

1、项目1 Java软件开发相关技术简介任务一 掌握Java语言基础知识任务二 掌握Java语言体系任务三 了解Java开发工具项目实战一 JDK安装配置及Java程序的编译运行1.1 任务一 掌握Java语言基础知识 1.1.1 Java语言的发展 Java是一个由Sun公司开发而成的新一代编程语言。使用它可在各式各样不同种机器、不同种操作平台的网络环境中开发软件。Java正在逐步成为Internet应用的主要开发语言。它彻底改变了应用软件的开发模式,带来了自PC机以来又一次技术革命,为迅速发展的信息世界增添了新的活力。 Java虽出现的时间不长,但已被业界接受,IBM、Apple、DEC、Ad

2、obe、Silicon Graphics、HP、Oracle、Toshiba、Netscape和Microsoft等大公司已经购买了Java的许可证。Microsoft还在其Web浏览器Explorer 3.0版中增加了对Java的支持。1JDK环境 Java不仅提供了一个丰富的语言和运行环境,而且还提供了一个免费的Java开发工具集(Java Developers Kits,简称JDK)。(1) Java编译器 Java程序的编译程序是javac.exe。javac命令将Java程序编译成字节码,然后你可用java解释器java命令来解释执行这些Java字节码。Java程序源码必须存放在后缀

3、为.java的文件里。Java程序里的每一个类,javac都将生成与类相同名称但后缀为.class文件。编译器把.class文件放在.java文件的同一个目录里 。1.1.2 Java程序开发与运行环境 (2) Java调试器 JDB(Java Debugger)是J2SDK提供的一个调试工具,可以实现单步跟踪、断点设置、监视程序输出情况等功能。在早期Beta l版的Java调试器中,JDB是命令行形式的,如Sun公司的DBX调试器。用JDB来调试Java应用程序,在调试之前,要确定应用程序是带标志-g编译的,例如javac -g HelloWorld.java。(3)Java解释器 Java

4、命令是由Java编译器javac输出的Java字节码。classname参数是要执行的类名称。注意任意在类名称后的参数都将传递给要执行类的main函数。Java执行完main函数后退出,除非main函数创建了一个或多个线程。如果main函数创建了其他线程,Java总是等到最后一个线程退出才退出。 1.1.3 Java语言特点1. 简单2. 面向对象3. 自动内存管理4. 分布计算5. 稳定性6. 安全性 7. 解释执行 8. 跨异构环境 9. 平滑移植10. 多线程11. 异常处理12. 可扩充1.1.4 Java 程序分类 Java程序分为两种类型:Java应用程序(Java Applica

5、tion)Java小应用程序(Java applet)。 Java Application可以独立运行;Java applet不能独立运行,可以使用Appletviewer或其他支持Java的浏览器运行。无论哪种Java程序,都用扩展名为.java的文件保存。1.1.5 JDK安装与环境变量配置 JDK(Java Developers Kit)即Java开发者工具包,也称为J2SDK(Java 2 Software Development Kit),是SUN公司提供的基础Java语言开发工具,该工具软件包含Java语言的编译工具、运行工具以及执行程序的环境(即JRE)。1JDK的下载 如果需要

6、获得最新版本的JDK,可以到Oracle公司的官方网站上进行下载。下载最新版本的JDK,选择对应的操作系统,以及使用的语言即可。2JDK的安装 Windows操作系统上的JDK安装程序是一个EXE可执行程序,直接安装即可,在安装过程中可以选择安装路径以及安装的组件等,如果没有特殊要求,选择默认设置即可。程序默认的安装路径在C:Program FilesJava目录下。3JDK环境变量的配置Java需要设置的环境变量有3个。(1)变量名JAVA_HOME;变量值“C:Program FilesJavajdk1.7”。变量值为你安装的JDK路径,在该路径下你应该能够找到bin、lib等目录,请根据

7、自己的实际情况填写。本例中的设置就应为“JAVA_HOME=C:ProgramFilesJavajdk1.7;”。注意:值后面不要加分号。注意:值后面不要加分号。(2)变量名PATH;变量值“%JAVA_HOME%bin;%JAVA_HOME%jrebin;”。 设置PATH的目的是为了设置指向JDK的bin目录,在bin目录下存放的是各种编译执行命令。本例中的设置就应该为“PATH=%JAVA_HOME%bin;%JAVA_HOME%jrebin;”。需要说明的是,系统本身就有PATH环境变量,只要把“%JAVA_HOME%bin;%JAVA_ HOME%jrebin;”直接放到后面即可,中

8、间使用“;”隔开。(3)变量名CLASSPATH;变量值“.;%JAVA_HOME%bin;%JAVA_HOME%libtools.jar;”。1.1.6 Java Application程序结构及运行过程1. 程序代码【例1-1】 HelloWorldpublic class HelloWorld public static void main(String args) System.out.println(Hello World !); 运行结果如下:Hello World !2程序解析(1)每个Java程序至少包含一个类的声明。 (2)成员方法由方法声明部分和方法体两部分构成 (3)标准

9、输出流3Java Application程序的结构特点 (1) 一个Java Application程序由一个或多个文件组成,每个文件中可以定义一个或多个类,每个类由若干个方法和变量组成。(2)一个文件中定义多个类时,允许其中声明零个或一个public类,若有public类则程序文件名必须与public类的类名相同,并区分大小写,扩展名为.java。(3) 一个Java Application程序仅有一个主方法main(),是整个程序的入口。 4Java程序编写中的注意事项v程序名必须与public类同名;Java程序区分大小写字母;Java程序中所有的方法都是属于某个类的,没有不属于某个类的

10、方法。v根据Java命名规范的约定,Java所有的类名都以一个大写字母开头,由多个词构成类名时每个词首字母大写。v程序中以“/”开头的为注释,称之为行注释,它不影响程序的编译与运行。vJava程序的书写格式很自由,一般采用紧缩对齐格式进行书写,Java语句用分号“;”作为语句的分隔标记,一般一行写一条语句,需一行可以写多条语句,一条语句也可以分成多行书写。5Java程序的编辑 编辑Java程序可以使用任何一种文本编辑器,例如UltraEdit、Notepad、Wordpad,然后只要把编辑好的文件保存为.java文件。当然也可以用一些集成开发环境完成编缉,例如Borland公司的JBuilde

11、r。6Java Application的执行 当编译结束以后,在Java源文件中的每一个类都会生成相应的 .class 文件,例如上例中就会生成一个HelloWorld.class文件,而Java程序在执行时调用的是.class 文件。Java Application的执行是在命令行下进行的,如果是在Windows系统中,就可以在命令提示符下敲入java HelloWorld进行执行,该Java命令会启动Java虚拟机,并读入HelloWorld.class文件执行。1.2 任务二 掌握Java语言体系 1.2.1 J2SE概述 Java 2平台包括标准版(J2SE)、企业版(J2EE)和微缩

12、版(J2ME)三个版本,也就是SunONE(Open Net Environment)体系。J2SE就是Java 2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入式系统开发,如手机和PDA的编程;J2EE是Java 2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。 从JDK 5.0开始,J2SE更名为Java SE,因为那个“2”已经失去了意义。 1.2.2 J2EE概述 Enterprise Edition(企业版) J2EE 包含J2SE 中的类,并且还包含用于开发企业级应用的类。比如:EJB、servlet、JSP、XML、事务控制。1.J2EE的概

13、念 J2EE是一种利用Java 2平台来简化企业解决方案的开发、部署和管理相关的复杂问题的体系结构。2. J2EE的优势(1)保留现存的IT资产(2)高效的开发(3)支持异构环境 (4)可伸缩性 (5)稳定的可用性3J2EE 的四层模型v运行在客户端机器上的客户层组件 ;v运行在J2EE服务器上的Web层组件 ;v运行在J2EE服务器上的业务逻辑层组件 ;v运行在EIS服务器上的企业信息系统(Enterprise information system)层软件。 4J2EE 的结构 这种基于组件,具有平台无关性的J2EE 结构使得J2EE 程序的编写十分简单,因为业务逻辑被封装成可复用的组件,并

14、且J2EE 服务器以容器的形式为所有的组件类型提供后台服务. 因为你不用自己开发这种服务, 所以你可以集中精力解决手头的业务问题。 容器和服务,容器设置定制了J2EE服务器所提供得内在支持,包括安全,事务管理,JNDI(Java Naming and Directory Interface)寻址,远程连接等服务,以下列出最重要的几种服务:JNDI 寻址(JNDI Lookup)服务向企业内的多重名字和目录服务提供了一个统一的接口。J2EE远程连接(Remote Client Connectivity)模型管理客户端和enterprise bean间的低层交互。 5. J2EE的核心API与组件

15、 J2EE平台由一整套服务(Services)、应用程序接口(APIs)和协议构成,它对开发基于Web的多层应用提供了功能支持,下面对J2EE中的13种技术规范进行简单的描述: vJDBC vJNDI vEJB vRMI vJava IDL/CORBA vJSP vJava Servlet vXML vJMS vJTA vJTS vJavaMail vJAF 1.2.3 J2ME概述 Micro Edition(微缩版) J2ME 包含J2SE中一部分类,用于消费类电子产品的软件开发。比如:呼机、智能卡、手机、PDA、机顶盒。1J2ME 是什么? Sun Microsystems 将 J2ME

16、 定义为“一种以广泛的消费性产品为目标的的高度优化的 JAVA 运行时环境,包括寻呼机、移动电话、可视电话、数字机顶盒和汽车导航系统。” Sun 在1999年6月时推出了 Java 2袖珍版 (J2ME)来满足消费电子和嵌入设备的需要。 2J2ME 总体架构 J2ME平台是由配置(Configuration)和简表(Profile)构成的。3. J2ME 目标设备1.3 任务三 了解Java开发工具 1.3.1 JBuilder简介 JBuilder是 Borland公 司 开 发 的 针 对 java的 开 发 工 具 , 使 用JBuilder将可以快速,有效的开发各类java应用,它使用

17、的JDK与sun公司标准的JDK不同,它经过了较多的修改,以便开发人员能够像开发Delphi应用那样开发java应用。Jbuilder的特点: 1. Jbuilder支持最新的Java技术,包括Applets、JSP/Servlets、JavaBean以及EJB (Enterprise JavaBeans)的应用。2. 用户可以自动地生成基于后端数据库表的EJB Java类,Jbuilder同时还简化了EJ B的自动部署功能.此外它还支持CORBA,相应的向导程序有助于用户全面地管理IDL(分布应用程序所必需的接口定义语言Interface Definition Language)和控制远程对

18、象。3. Jbuilder支持各种应用服务器。Jbuilder与Inprise Application Server紧密集成,同时支持WebLogic Server,支持EJB 1.1和EJB 2.0,可以快速开发J2EE的电子商务应用。4. Jbuilder能用Servlet和JSP开发和调试动态Web 应用。 利用Jbuilder可创建(没有专有代码和标记)纯Java2应用。由于Jbuilder是用纯J ava语言编写的,其代码不含任何专属代码和标记,它支持最新的Java标准。 Jbuilder拥有专业化的图形调试介面,支持远程调试和多线程调试,调试器支持各种JDK版本,包括J2ME/J2

19、SE/J2EE。JBuilder环境开发程序方便,它是纯的Java 开发环境,适合企业的J2EE开发;缺点是往往一开始人们难于把握整个程序各部分之间的关系,对机器的硬件要求较高,比较吃内存,这时运行速度显得较慢1.3.2 Eclipse简介1. 历史背景 Eclipse这样功能完整且成熟的开发环境,是由蓝色巨人 IBM所研制。IBM花了4千万美金来开发这个IDE(Integrated Development Environment)。第一版1.0在2001年11月面市,随后逐渐受到欢迎。2. 开放原始码软件 Eclipse使用的开放原始码许可书:公共公众许可书-Common Public Li

20、cense(CPL)作为授权方式,设计上是可以容许商业利益的。3跨语言、跨平台 多数人认为Eclipse是Java IDE,不过,当下载Eclipse之后,除了有Java IDE(即JDT),还有PDE。然而Eclipse是万用工具平台。JDT实际上是Eclipse的添加品,也就是外挂程序。Eclipse本身实际上是指Eclipse平台(Eclipse Platform),除了下载时能取得Java工具集以外,还提供各种工具的支持,所以平台本身只是相当小的一组软件。如果想开发Java程序,用的是Eclipse随附的JDT外挂程序。如果想开发其他语言的程序,就需要拿到其他外挂程序,例如CDT(C

21、Development Toolkit)就可以开发C/C+程序。1.3.3 其它开发工具简介 Java的开发工具很多,而且各有优缺点,本节对常用的Java开发工具作一介绍,有助于读者了解Java常用开发工具并做出选择。Java的开发工具分成三大类,现介绍如下: (1)文本编辑器。这类工具只提供了文本编辑功能,它只是一种类似记事本的工具。这类工具进行多种编程语言的开发,如C、C+、Java等。在这个大类中,本书主要介绍UltraEdit和EditPlus两种编辑器。(2)Web开发工具。这类工具提供了Web页面的编辑功能,具体到Java主要就是JSP页面的开发。(3)集成开发工具。这类工具提供了

22、Java的集成开发环境,为那些需要集成Java与J2EE 的开发者或开发团队提供对Web Application、Servlets、JSP、EJB、数据访问和企业应用的强大支持。现在的很多工具属于这种类型,也是Java开发工具的发展趋势。1.4 项目实战一 JDK安装配置及Java程序的编译运行1.实战内容 本实战要求学生下载安装JDK 1.7,并对JAVA_HOME、PATH和CLASSPATH环境变量进行配置;同时自己编写并调试一个Java应用程序,了解Java 程序的编译运行。对于学有余力的学生可尝试下载安装本章介绍的Eclipse、JBuilder、JCreator和JCreator等

23、集成开发环境中的一种,并在其中编辑、编译和运行Java Application和Java Applet程序。2.实战目的通过实战,读者熟练掌握JDK安装配置及JAVA程序的编译方法。3.实战过程:(1)下载安装。(2)配置环境变量,涉及到java_home,classpath,Path ,按Win+Break打开系统属性,单击【高级】选项卡,单击【环境变量】按钮,单击【添加】。(3)首先设置java_home变量,在“变量名”中填写java_home,“变量值”根据安装目录填写。(4)按照上面的方法,分别填写classpath和Path。(5)设置完成后保存设置,重新启动计算机或注销后再登陆。

24、(6)用记事本编写如下程序,注意大小写。class HelloJava public static void main(String args) System.out.println(Hello Java!); (7)保存为HelloJava.txt再把后缀名改为java,注意文件名的大小写 。(8)用Win+R(或单击开始运行),输入cmd回车 。(9)转到HelloJava.java所在的目录。 (10)输入javac HelloJava.java编译,没有任何提示编译通过 。(11)输入java HelloJava运行,如果输出Hello Java!表示配置成功,否则参考以上步骤,查找错

25、误原因。项目小结 重点介绍了Java 运行环境与开发环境,JDK安装与环境变量配置及Java Application程序结构及运行过程;希望读者掌握Java程序的编辑、编译、运行及调试(javac、java)操作。(1)主要内容。 1)Java语言的发展简史。 2)Java语言的特点及优势。 3)Java程序分类、Java语言体系概述。 4)Java的运行环境与开发环境,Java开发工具。 5)简单Java程序设计。 6)JDK安装与环境变量配置,Java Application程序结构及运行过程。 7)Java的编码规范。(2)重点内容。 1)JDK的下载安装与JAVA_HOME、CLASS

26、PATH、PATH环境变量的设置。 2)Java程序的编辑、编译、运行及调试(javac、java)。项目项目2 Eclipse2 Eclipse基本操作基本操作 任务一:了解Eclipse概况任务二:掌握Eclipse安装与配置任务三:掌握Eclipse工作环境任务四:使用Eclipse进行Java编程项目实战一 Eclipse的安装配置及Java程序的调试运行2.1 任务一 了解Eclipse概况 2.1.1 Eclipse历史与发展 2001年IBM把基于JAVA开发的集成平台软件Eclipse捐献给开放源代码社区,并成立Eclipse协会,支持并促进Eclipse开源项目。2004年E

27、clipse协会脱离IBM独立,并命名为Eclipse基金会.2006年6月Eclipse基金会发布了Eclipse3.2,它不但可以在Windows和Linux操作系统上运行,还可以支持Solaris操作系统。2.1.2 Eclipse特点 1.开放的开发平台 Eclipse是完全开放的,任何人都可以参与。参与最简单的办法是加入它的新闻组,选择一个感兴趣的技术领域,然后下载代码,自己做实验,随着技术的提高就可以提交Bug包和修复包,并修复其它的Bug。如果得到项目组的认可,便可以参加项目开发工作。 2强大的插件扩展机制和插件加载功能 插件也称为扩展,是遵循一定规范的应用程序接口。借助于原有开

28、发环境安装各种插件可以增强并扩展原有软件的功能。 Eclipse插件扩展机制是其最突出的特点和优势。通过安装不同的插件来增加它的功能,如通过安装插件可以实现HTML编辑、数据库设计、JAVA开发、C+开发等,其实Eclipse本身就是一系列插件的集合。 2.2 任务二 掌握Eclipse安装与配置2.2.1 Eclipse下载与安装 Eclipse是开放源代码,完全免费的,可以在它的官方网站www.eclipse.org下载。需要注意的是,在使用Eclipse之前首先要安装JDK。2.2.2 Eclipse多国语言包的安装 Eclise本身是英文的,如果要汉化就要安装与其版本号相同的多国语言包

29、。多国语言包可以免费在eclipse官方站下载。下载后我们可以采用LINK安装方式:1多国语言包下载成功后在eclipse的安装目录内新建一个文件夹,并命名为language,假设eclipse在D盘,即:D:eclipselanguage;2. 将解压后的语言包(名为eclipse)解压到language文件夹下;3. 在eclipse的安装目录内新建一个文件夹,并命名为links ,即:D:eclipselinks;4. 在links文件夹下再新建一个文本文档,并为该文档命名为“language.txt”,然后在文档内编辑如下内容:path=D:Eclipselanguage (注意:路径

30、分隔符由两个反斜扛组成),编辑完成保存后将.txt后缀名改为.link;5. 重新启动eclipse,便成功变为中文版eclipse 在做完上述工作后,为了确保eclipse正常使用,一般还需要做一些配置。1eclipse文本编辑器编码设置;在eclipse主菜单中选择“窗口”菜单中的“首选项”,然后在左侧目录树中选择“常规”,再选“工作空间”,在下面可以看到“文本文件编码” 2.2.3 Eclipse相关配置图2-2 首选项对话框2验证JRE路径变量第一次使作时最好验证一下JRE(JAVA运行环境)。选“窗口”菜单中“首选项”,再左侧目录树中选项择“JAVA”,再选“已安装的JRE”图2-3

31、 验证JRE2.3 任务三 掌握Eclipse工作环境2.3.1 Eclipse结构体系Eclipse是一个开放的、可扩展的体系结构,Eclispe是世界上最大的开源组织的产品,是一个基于Java的可扩展的开发平台,就其本身来说,它只是一个框架和一组服务,用于通过组件构建开发环境。 Eclipse 是一个全能的工作平台,主要得益于其插件体系结构。整个Eclipse采用平台加插件体系结构 启动时Eclipse会检查所有的插件并注册,但是直到被调用,该插件的才会被实例化,这也就是我们常说的懒加载。 Eclipse平台分为核心和用户界面。核心的事项隐藏在后台运行,用户界面部分称为工作台 1平台运行时

32、2工作空间3工作台2.3.2 Eclipse工作台 工作台窗口如图2-5所示,主要由以下几部分组成:标题栏、菜单栏、工具栏、透视图。1.透视图 透视图包含一组视图和编辑器并可以方便地对它们进行布局,透视图的作用是将一些视图打开并摆好位置、显示菜单、添加快捷键等工作,并没有做任何与功能相关的操作 (1)打开透视图 选择【窗口】菜单,打开【透视图】子菜单,在弹出的菜单中选择【其它】命令,这时会弹出“打开透视图”对话框 (2)保存透视图 选择【窗口】菜单,打开【将透视图另存为】命令(3)关闭透视图 在工作台菜单中选择【窗口】,选择【关闭透视图】可以关闭当前所选透视图,选择【关闭所有透视图】可以关闭所

33、有已打开的透视图 图2-5 Eclipse工作台窗口 2视图视图用于支持编辑器并提供浏览工作台中的信息的备用显示和方法。视图可能会单独出现,也可能与其他视图叠放在一起。在工作台窗口中,可通过打开和关闭视图及通过将它们放在不同的位置来更改透视图的布局。3编辑器 在工作台中有一个编辑器区域,根据文件类型的不同工作台会采用不同的编辑器。如果要打开一个文本文件则文本编辑器会显示在编辑区中;如果要打开一个网页文件则Web浏览器将显示在编辑区中2.3.3 Eclipse资源管理资源是存在于工作台中的项目、文件夹和文件和统称。其中项目是用于构建、版本管理共享和组织资源。在磁盘上会有一个与项目同名的目录,里面

34、包含项目中的文件夹和文件. 1创建资源(1)创建项目在Eclipse中一般都通过创建一个项目来管理资源,项目是与开发相关的各种资源的集合。在菜单栏中选择【文件】中的【新建】命令,在下拉菜单中选择【项目】, 图2-7 新建项目对话框 2管理资源利用“导航器”视图以很方便地对工作台中各种资源进行浏览,它类似于Windows的资源管理器,可以方便地对资源进行各种操作。当需要对某个资源进行操作时,在“导航器”中选取这个资源,单击右键,在如图2-9所示的快捷菜单中选取相应的命令即可进行新建、复制、移动、删除、运行等各种操作。图2-9 创建文件夹2.4 任务四 使用Eclipse进行Java编程 2.4.

35、1 编辑Java程序 下面我们以编写一个HelloWorld程序为例,讲解如何使用Eclipse进行Java程序的编辑。步骤如下: (1)打开Eclipse后,选择“文件”“新建”“项目”命令,在项目列表中选择Java项目,单击“下一步”按钮,输入项目名称,例如HelloProject,单击“完成”按钮。 如果已经有建好的项目,这步可以省略,直接在项目中创建Java文件即可。 (2)在左侧的“导航器”视图中选中项目名或项目中的文件夹,右击,在快捷菜单中选择“类”项(带有一个C标记),如图2-10所示。(3)在弹出的如图2-11所示的对话框的“名称”文本框中输入Java类文件的名字HelloWo

36、rld;选中public static void main(String args)复选框,让Eclipse创建main方法,单击“完成”按钮(图2-11中可以看到一个“建议不要使用缺省包”的提示,这并不影响使用,但一般情况下最好在项目中建一个文件夹,把Java文件建立在文件夹中)。(4)在如图2-12所示的Java编辑窗口中的main方法中输入“System.out.println(Hello World);”。(5)按Ctrl+S键保存,将自动编译HelloWorld.java。(6)单击工具栏中的的“运行”按钮,选择“Java应用程序”;或者右击,在快捷菜单中选择“运行方式”“Java应

37、用程序”命令。这时将会在下面打开一个控制台窗口,一句“Hello World”将会显示在里面。 2.4.2 编译和运行程序 我们可以选择“项目”菜单中的“自动构建”命令,这样每次保存工作台中资源时都会自动编译。如果编译没有错误,可以在“导航器”视图中看到相应的class文件。 编译通过后有两种方式来启动程序,即运行方式和调试方式。在运行方式下,程序可以被执行但不能被挂起检查。在调试方式下,程序可以被挂起和继续执行,可以检查变量等。由于调试时是以行为单位运行的,因此写程序时最好不要把多个语句放到一行上。 在Eclipse中提供多种跟踪方式,断点设置,变量值察看窗口等等。在Java视图中,工具栏中

38、有两个按钮,分别用来进行调试和运行。并且可能由于安装的插件不同Eclipse会存在多种运行/调试程序的方式,我们可以在程序编辑窗口单击右键,在快捷菜单中选择“运行方式”,在下级菜单中会根据程序类型自动出现“Java应用程序”或者“Java Applet”,然后选择运行即可 2.4.3 调试程序 调试时可以选择“运行”菜单中的“调试”命令。为了方便调试,可以用“窗口”菜单中“显示视图”,再选“其它”中的“调试”,在其下级菜单中再选“调试” 视图中显示调试的状态,在下面的“调试”窗口单击右键在快捷菜单中可以选择相应的命令完成调试各种操作。下面把其中的一些命令解释一下。 1)暂挂:把正在执行的程序挂

39、起,用户可以查看堆栈中的信息。在调试视图中也会显示堆栈中对应的代码。 2)继续:结束挂起状态,继续执行程序。 3)终止;结束程序执行4)单步跳过:不进入调用的方法内部,而是在该方法下一个方法前挂起。5)单步跳入:正单步跳过相反,进入方法内部。6)单步返回:如果进入方法内部看到了期望的结果,可以用这个命令从方法返回。7)使用单步执行过滤器:为了避免在调试中出现中断情况可以使用这个功能。中断是由于在没有源代码的情况下使用单步执行进入调用方法而导致的。中断发生时会弹出一个窗口,要求输入代码的位置。在过滤器中设置的各种包和类在单步进入时,调试器就不会弹出中断窗口。2.5 项目实战一 Eclipse的安

40、装配置及Java程序的调试运行1.实战内容在Eclipse下编辑调试计算并显示1到200间所有奇数的和程序并运行显示结果。 2.实战目的要求读者运用前面所学的eclipse相关知识,熟练掌握eclipse安装配置及利用eclipse进行Java程序的编辑及调试技能。3.实战过程(1)安装Eclipse4.3.2软件包eclipse-SDK-432-win32.zip到D盘eclipse子目录;(2)安装Eclipse汉化包BabelLanguagePack-eclipse-zh_3.6.0.v20120721114722.zip到eclipse子目录并配置;(3) 启动Eclipse后创建一个

41、项目,然后新建一个Java类文件,在编辑窗口输入如下程序代码:public class exo2_1 public static void main (String args) int s=0; for(int i=1;i大于,二元运算符xy小于,二元运算符x=大于等于,二元运算符x=y=小于等于,二元运算符x3)&(x3)|(x3)&(x3)|(x10)【例3-4】 逻辑运算符的演示public class Testpublic static void main(String args) System.out.println( x y & | + & |); System.out.print

42、ln(-+-); boolean x,y,b1,b2,b3,b4,b5;x=true;y=true;b1=x&y;b2=x|y;b3=xy;b4=x&y;b5=x|y;System.out.println(x+t+y+t+b1+t+b2+t+b3+t+b4+t+b5);x=true;y=false;b1=x&y; b2=x|y;b3=xy;b4=x&y;b5=x|y;System.out.println(x+t+y+t+b1+t+b2+t+b3+t+b4+t+b5);x=false;y=false;b1=x&y;b2=x|y;b3=xy;b4=x&y;b5=x|y;System.out.pri

43、ntln(x+t+y+t+b1+t+b2+t+b3+t+b4+t+b5);5.条件运算符条件运算符?:是Java中唯一的一个三元运算符,由它构成的条件表达式格式如下:条件?结果1:结果2条件运算符的计算过程:首先计算条件,如果为真,则整个表达式的值为结果1,否则为结果2。6.位运算符位运算符的具体内容见表3-9。表3-9位运算符运 算 符含 义举 例位非,每一位求反,一元运算符a&位与,二元运算符a&b|位或,二元运算符a|b位异或,二元运算符ab位左移,每一位左移,二元运算符a位右移,每一位右移,二元运算符ab位右移,每一位右移,原位补零,二元运算符ab【例【例3-53-5】 位运算符的演示

44、位运算符的演示public class Testpublic static void main(String args)int x=10;/00001010int y=2;/00000010int z;/位非z=x;/11110101System.out.println(z=+z);/-11/位与&z=x&y;/00000010System.out.println(z=+z);/2/位与|z=x|y;/00001010System.out.println(z=+z);/10/位异或z=xy;/00001000System.out.println(z=+z);/8/位左移z=xy;System.

45、out.println(z=+z);/2/位右移z=xy;System.out.println(z=+z);/27.其他运算符在Java中,还有一些特殊的运算符,见表3-10。表3-10其他运算符运 算 符含 义举 例( )如果表达式加上括号,表示优先运算(x+y)*2(参数表) 方法在传递参数时使用int add(int x,int y)(类型)强制类型转换(int)x.引用对象的属性或方法greeting.substring(0,4)引用数组元素a3instanceof测试一个对象是否是一个指定类的实例a instance of Animalnew对象实例化运算符Animal a=new

46、Animal()+字符串合并运算符Hello+World8.运算符优先级表3-11运算符的优先级1.( )expr+expr-2+expr-expr!-3new(type)4*/%5+-67=instanceof8=!=9&1011|12&13|14?:15=opr=3.3.2 表达式 所谓表达式,就是由操作数和运算符按照一定的规则组成的式子,它可以进行计算并能够求出具体的值。操作数可以是任意的常量、变量和方法等。例如: double area=3.14*r*r;3.4 任务四 掌握Java数组及字符串的使用3.4.1数组的声明与创建 数组是用来存储一组相同类型数据的数据结构,可以通过整型下标

47、来访问数组中的每一个值。定义数组的语法格式如下:数据类型数组名;数据类型数组名=new数据类型元素个数; 3.4.2 数组的初始化及数组元素的使用 1. 数组的初始化 数组的初始化有多种形式,上一节已经讲了一种,不过,本节讲数组初始化的简化形式,举例如下: /初始化数组变量int a=1,3,5,7,9; 2. 数组元素的使用 声明并初始化一个数组变量后,可以通过变量名和相应的下标来访问数组中的指定元素。例如:int a=new int1,3,5,7,9; 【例3-6】 数组声明、初始化和使用演示public class Testpublic static void main(String a

48、rgs)int a1=new int1,3,5,7,9;int a2=2,4,6,8,10;/输出数组a1for(int i=0;i5;i+)System.out.print(a1i+ );System.out.println();/输出数组a2for(int i=0;i5;i+)System.out.print(a2i+ ); 3.4.3 字符数组与字符串String类1. 字符数组 【例3-7】 字符数组演示public class Testpublic static void main(String args)char answers=new charA,B,C,D;char optio

49、ns=1,2,3,4;for(int i=0;i4;i+)System.out.print(answersi+ );System.out.println();for(int i=0;i4;i+)System.out.print(optionsi+ ); 2. 字符串String类 字符串指的是一个字符序列,比如“Hello World”,在Java语言中,并没有内置的字符串类型,而是在标准的JDK中提供了一个名为String的预定义的类。 3.4.4 字符串数组一个字符串是一个字符序列,或者说是一个字符数组,而一个字符串数组则是若干个字符串,或者说是若干个字符序列,例如:Stringcitie

50、s=newStringBeijing,Shanghai,Tianjin,Chongqing;【例3-8】字符串数组演示publicclassTestpublicstaticvoidmain(Stringargs)Stringnames=newStringMike,Tom,Kate,John;for(inti=0;i4;i+)System.out.println(namesi);3.4.5 3.4.5 字符串相关操作字符串相关操作1.字符串连接同大多数语言一样,Java允许使用符号+把两个字符串连接起来。2.求子串String类中的substring方法可以从一个字符串中提取它的子串。该方法一个

51、原型如下:Stringsubstring(intbeginIndex,intendIndex)3.求字符串的长度String类中的length方法可以求取字符串的长度。该方法原型为:intlength()4.测试字符串内容是否相等String类中的equals方法可以测试两个字符串的内容是否相等,注意区分大小写,如果要忽略大小写,可以使用equalsIgnoreCase方法,它们的原型如下:booleanequals(Objectother)/如果字符串与other相等,返回truebooleanequalsIgnoreCase(Stringother)/如果字符串与other相等(忽略大小写

52、),返回true5.大小写转换操作在String类中,toUpperCase方法可以把原串中所有的小写字母转换成大写,返回转换后的新串,toLowerCase方法可以把原串中所有的大写字母转换成小写,返回转换后的新串。它们的原型如下:StringtoUpperCase()StringtoLowerCase()【例【例3-93-9】 字符串常用操作演示字符串常用操作演示public class Test public static void main(String args)/1.字符串连接String greeting1=Hello;String greeting2=World;String

53、greeting= greeting1+greeting2;System.out.println(greeting);/2.求子串String s=greeting1.substring(0,4);System.out.println(s);/3.求字符串的长度int n=greeting1.length();System.out.println(n);/4.测试字符串内容是否相等String greeting3=Hello;String greeting4=hello;boolean b1=greeting1.equals(greeting3);boolean b2=greeting1.eq

54、uals(greeting4);boolean b3=greeting1.equalsIgnoreCase (greeting3);booleanb4=greeting1.equalsIgnoreCase(greeting4);System.out.println(b1=+b1);System.out.println(b2=+b2);System.out.println(b3=+b3);System.out.println(b4=+b4);/5.大小写转换操作Stringuppergreeting=greeting1.toUpperCase();Stringlowergreeting=gree

55、ting1.toLowerCase();System.out.println(uppergreeting);System.out.println(lowergreeting);3.5 项目实战一 数组的使用1.实战内容 编写一段代码,通过数组来存储并显示班级学生的姓名和年龄。2.实战目的(1) 掌握数组的创建方法(2) 熟悉数组初始化的方法(3) 掌握使用数组元素的方法3.实战过程(1)打开Eclipse代码编辑器,输入如下代码:public class Testpublic static void main(String args)String names=张秀,王凯,李丽,赵刚,刘珂;in

56、t ages=20,21,20,19,18;for(int i=0;i5;i+)System.out.println(姓名:+namesi+t年龄:+agesi);(2)通过Eclipse运行程序。3.6 项目实战二 字符串的使用1.实战内容 编写一段代码,实现字符串的截取和连接等操作2.实训目的 通过本次实战,掌握字符串变量的声明方法,熟练使用字符串数组和字符串常用方法。3.实训过程(1)打开Eclipse代码编辑器,输入如下代码:public class Testpublic static void main(String args)String msg=孤帆远影碧空尽,唯见长江天际流;i

57、nt len;String tmp;tmp=msg0.substring(0,4);len=tmp.length();System.out.println(部分内容:+tmp+t长度:+len);tmp=msg0+,+msg1;len=tmp.length();System.out.println(全部内容:+tmp+t长度:+len);(2)通过Eclipse运行程序。项目小结 首先介绍了Java语言中的关键字、标识符和分隔符,介绍了Java中的基本数据类型、常量和变量的定义及作用范围、基本数据类型间的转换,对Java中的常用运算符和表达式进行了详细讲解,介绍了Java中的数组的声明和初始化

58、方法及数组元素的使用,介绍了字符数组、字符串数组及字符串的相关操作,最后通过实战强化练习了数组的创建以及字符串的使用。项目4 基本控制结构任务一 掌握Java分支结构任务二 掌握Java循环结构项目实战一 分支结构编程项目实战二 循环结构编程 4.1 任务一 掌握Java分支结构 4.1.1if语句1.简单的条件语句语句的格式如下:if(表达式)语句;图4-1简单的条件语句说明:(1) 放在if之后的括号里的只能是一个逻辑表达式,即这个表达式的返回值只能是true或false。(2) 如果表达式的值为true,则执行语句;如果表达式的值为false,则什么也不执行。(3) 花括号括起来的语句块

59、可以只有一行语句,也可以由多行代码构成。一个语句块通常被当成一个整体来执行。 如果语句块只有一行语句时,则可以省略花括号,因为单行语句本身就是一个整体,无须花括号来把它们定义成一个整体。【例【例4-14-1】通过命令行输入一个人的年龄,判断其是否为未成年人。import java.io.*;public class TestAge public static void main(String args) throws IOException InputStreamReader in=new InputStreamReader(System.in); BufferedReader bin=new

60、 BufferedReader(in); int age;System.out.println(请输入一个年龄,回车); age=Integer.parseInt(bin.readLine(); if(ageb) t=a;a=b;b=t; if(ac) t=a; a=c; c=t;if(bc) t=b; b=c; c=t; System.out.println(a=+a+,b=+b+,c=+c); 2. 带else的条件语句语句的格式如下:if(表达式)语句1;else语句2;图 4-2 带else的条件语句说明:(1)放在if之后的括号里的只能是一个逻辑表达式,即这个表达式的返回值只能是tr

61、ue或false。(2)如果if表达式的值为true,则执行语句1;如果表达式的值为false,则执行语句2。【例4-3】判断一个年份是否为闰年,是则显示,否则提示某年不是闰年。(闰年的判断规则:如果某年能被4整除且不能被100整除;或者某年能被400整除)import java.io.*;public class TestYear public static void main(String args) throws IOException InputStreamReader in=new InputStreamReader(System.in); BufferedReader bin=ne

62、w BufferedReader(in);int year;System.out.println(请输入一个年份,回车);year=Integer.parseInt(bin.readLine(); if(year%4=0 &(year%100!=0)|(year%400=0) System.out.println(year+是闰年!);elseSystem.out.println(year+不是闰年!);【例4-4】通过命令输入两个数,把它们由大到小输出。import java.io.*;public class TestNum public static void main(String a

63、rgs) throws IOException InputStreamReader in=new InputStreamReader(System.in); BufferedReader bin=new BufferedReader(in); float x,y; System.out.println(请输入第一个数);x=Float.parseFloat(bin.readLine();System.out.println(请输入第二个数);y=Float.parseFloat(bin.readLine(); if(xy) System.out.println(x+,+y);elseSyste

64、m.out.println(y+,+x); 3. if语句的嵌套 在if语句中又包含一个或多个if语句称为if语句的嵌套。语句的格式如下:if(表达式1)语句1;else if(表达式2)语句2;else if(表达式m)语句m;else 语句n;【例【例4-54-5】根据百分制分数判定成绩等级,标准如下:A:90100分B:8089分C:7079分D:6069分E:60分以下public class TestGrade public static void main(String args) int score=89; char ch; if(score=90)ch=A; else if(s

65、core=80)ch=B; else if(score=70)ch=C; else if(score=60)ch=D; else ch=E; System.out.println(等级+ch); Java提供了多分支选择语switch语句。使用switch可以测试多个不同的条件并做出相对的响应。 switch(表达式) case 常量1:语句序列1; break;case 常量2:语句序列2; break;case 常量n:语句序列n; break; default:语句序列n+1; 4.1.2 switch语句说明:说明:(1)表达式的数据类型可以是byte、short、char和int类型

66、,不允许是浮点数类型和long类型。break语句和default子句是可选项。(2)switch语句先计算表达式的值,然后依次匹配case子句后的常量1、常量2常量n等值,如果遇到匹配的值即执行对应的语句序列,直到遇到break语句为止;如果case子句中没有break语句,则程序继续匹配剩余case子句后的值。(3)如果没有一个常量值与表达式的值相等,则执行default子句中的语句序列;如果没有default子句,switch语句不执行任何操作。【例【例4-64-6】根据不同的运算符号(+、-、*、/),对两个数执行相应的运算并输出结果。import java.io.*;public c

67、lass TestSign public static void main(String args) throws IOExceptionfloat a=10f,b=5f,c=0.0f;char sign;System.out.println(加法(+),减法(-),乘法(*),除法(/),请选择运算符);sign=(char)System.in.read(); switch(sign) case +:c=a+b; break; case -:c=a-b; break; case *:c=a*b; break; case /:c=a/b; break; default: System.out.

68、println(输入符号错误!); c=-1.0f; if (c!=-1.0f)System.out.println(a=+a+b=+b+c=+c);【例4-7】根据用户输入17之间的一个整数,输出相对应星期的英文单词。import java.io.*;public class TestWeek public static void main(String args) throws IOException InputStreamReader in=new InputStreamReader(System.in); BufferedReader bin=new BufferedReader(in

69、);short day;System.out.println(请输入17之间的一个整数);day=Short.parseShort(bin.readLine();switch(day)case 1:System.out.println(Monday);break; case 2:System.out.println(Tuesday);break;case 3:System.out.println(Wednesday);break;case 4:System.out.println(Thursday);break;case 5:System.out.println(Friday);break;c

70、ase 6:System.out.println(Saturday);break;case 7:System.out.println(Sunday);break; default: System.out.println(请输入17之间的一个数!); 4.2 任务二 掌握Java循环结构 循环结构是程序中一种重要的基本结构,是指在一定的条件下重复执行某段程序,被重复执行的这段程序称为“循环体”。 Java还提供了break语句和continue语句,可以控制循环语句的执行情况。1. break语句2. continue语句 continue语句的功能和break语句有点类似,区别是continu

71、e语句只是终止本次循环,回到循环条件处,判断是否执行下一次循环。而break语句则是完全终止循环。可以理解为continue语句的作用是略过当次循环中剩下的语句,重新开始新的循环。 4.2.1 for语句语句的格式如下:for(表达式1; 表达式2; 表达式3)循环体;图 4-4 for语句流程图说明:(1)表达式1一般是一个或多个(用逗号隔开)赋值语句,它用来给循环控制变量赋初值;表达式2是一个布尔类型的表达式,它决定什么时候退出循环;表达式3一般用来修改循环变量,控制变量每循环一次后按什么方式变化。这三个部分之间用“;”分开。 (2)for语句的执行过程:在循环刚开始时,先计算表达式1,在

72、这个过程中,一般完成的是初始化循环变量或其它变量。根据表达式2的值来决定是否执行循环体。表达式2是一个返回布尔值的表达式,若该值为假,将不执行循环体,并退出循环;若该值为真,将执行循环体。执行完一次循环体后,计算表达式3。每次执行循环体之后都要重新验证表达式2的值,直到表达式2的值为false时退出循环。(3)循环体可以是一条简单语句,此时可以省略循环体外的花括号。循环体也可以是一组语句块,此时不可以省略循环体外的花括号。【例【例4-84-8】输出19之间的所有整数及其平方值。public class TestNum1 public static void main(String args)

73、for(int i=0,j=0;i=9;i+,j=i*i) System.out.println(i=+i);System.out.println(j=+j); 【例【例4-94-9】计算1100之间的偶数和。public class TestNum2 public static void main(String args) int n,s=0;for(n=0;n=100;n=n+2) s=s+n; System.out.println(2+4+100=+s); 4.2.2 dowhile语句语句的格式如下:do循环体;while(表达式);图 4-5 do-while语句流程图说明:说明:(

74、1)放在while之后的括号里的只能是一个布尔表达式。布尔表达式表示循环执行的条件。(2)循环体可以是一条语句,也可以是复合的语句序列。如果只有单个语句需要重复,花括号可以省略。(3)dowhile语句的执行过程是:先执行一次循环体再判断布尔表达式的值,当布尔表达式的值为true时重复执行循环体中的语句,每次执行循环体之后都要重新验证表达式的值,直到表达式的值为false时退出循环。一定要有使布尔表达式的值取假的时候,否则会出现死循环。(4)特点:先执行循环体,然后判断循环条件是否成立,dowhile语句总是执行它的循环体至少一次。【例【例4-124-12】计算1100之间的整数和。publi

75、c class TestNum3public static void main(String args) int n=1,s=0; do s=s+n; while(+n=100); System.out.println(1100之间的整数和为: +s);4.2.3 while语句语句的格式如下:while(表达式) 循环体;图 4-6 while语句流程图说明:说明:(1)放在while之后的括号里的只能是一个布尔表达式。布尔表达式表示循环执行的条件。(2)循环体可以是一条语句,也可以是复合的语句序列。如果只有单个语句需要重复,花括号可以省略。(3)while循环语句的执行流程:先判断whil

76、e语句中的布尔表达式的值;如果是false,则不执行循环体,直接执行后面的程序;如果是true,则执行循环体语句,然后重新验证表达式的值,直到表达式的值为假时退出循环。(4)while语句的特点是先判断表达式值为真后,再执行循环体。如果while循环一开始布尔表达式的值就是假的,那么循环体就根本不被执行。 【例4-14】编程输出100400之间能同时被3和7整除的数。public class TestNum5public static void main(String args) int n=100; while(n=400)if(n%3=0 &(n%7=0)System.out.print(

77、n+ );n+;4.2.4 嵌套循环如果在循环语句的循环体中又包含循环语句,就形成多重循环结构,称为嵌套循环。嵌套循环既可以是for循环嵌套while循环,也可以是while循环嵌套dowhile循环即各种类型的循环都可以作为外层循环,各种类型的循环也可以作为内层循环。当程序遇到嵌套循环时,如果外层循环的循环条件允许,则开始执行外层循环的循环体,而内层循环将被外层循环的循环体来执行只是内层循环需要反复执行自己的循环体而已。当内层循环执行结束、且外层循环的循环体执行结束,则再次计算外层循环的循环条件,决定是否再次开始执行外层循环的循环体。 根据上面分析,假设外层循环的循环次数为i次,内层循环的循

78、环次数为j次,那么内层循环的循环体实际上需要执行i*j次。 嵌套循环不仅可以是两层嵌套,还可以是三层嵌套,四层嵌套不论循环如何嵌套,我们都可以把内层循环当成外层循环的循环体来对待,区别只是这个循环体里包含了需要反复执行的代码。 循环嵌套时,要求内循环完全包含在外循环之内,不允许出现相互交叉 【例【例4-174-17】利用双重循环,输出九九乘法表:public class Tablepublic static void main(String args) int m, n; for(m=1;m=9;m+) for(n=1;n=9;n+)System.out.print(m+*+n+=+(m*n)

79、+t);System.out.println(); 4.3 项目实战一 分支结构编程1.实战内容利用if语句编写程序根据给定的x值计算分段函数y的值。 x(x0) y = 4x8 (0x30) x10(x30)2.实战目的掌握分支结构编程方法。3.实战过程 由于y是关于x的一个分段函数,所以要在main()方法中声明两个float类型的变量,分别表示变量x与y。变量x应设计成可以由用户从键盘输入;变量y根据x的取值,计算不同算式的值,因为要判断变量x的3种取值区间,本程序采用带嵌套的if语句来完成多个条件的判定。程序编写如下:import java.io.*;public class Test

80、Function public static void main(String args) throws IOException InputStreamReader in=new InputStreamReader(System.in); BufferedReader bin=new BufferedReader(in); float x,y; System.out.println(请输入x的值); x=Integer.parseInt(bin.readLine(); if(x0&x30)y=x-10; System.out.println(x=+x); System.out.println(

81、y=+y); 4.4 项目实战二 循环结构编程1.实战内容 利用for语句,编程输出空心菱形,如下所示: * * * * * * * * * * * *2.实战目的 熟悉循环结构编程方法。3.实战过程 把空心菱形分成上下两部分分别输出,每部分分为多行需要使用循环结构,每行的星号和空格都需要使用需要循环结构,所以本程序需要使用两次二重循环。声明两个int类型变量i、j,分别用来控制外循环和内循环的循环次数。程序编写如下:public class ffpublic static void main(String args)for(int i=1;i5;i+) /上三角;System.out.pri

82、nt(t);for(int k=0;k4-i;k+) System.out.print( );/输出前面的空格System.out.print(*);for(int j=0;j0;i-)/下三角;System.out.print(t);for(int k=0;k4-i;k+) System.out.print( ); /输出前面的空格 System.out.print(*); for(int j=0;jb)?a:b; return c;说明:说明:(1)方法的修饰符是用于指定本方法的访问权限和特性,例如,方法是否为公有方法或类方法等。方法的修饰符有以下几种: public|private|pr

83、otected|default:该修饰符被称为访问控制修饰符,其规定了成员方法的可见范围。例如,public访问修饰符表示该方法可以被任何其他代码调用,而private表示方法只能被类中的其他方法调用。 static该修饰符声明了本方法是类方法。 final该修饰符声明了本方法为不可被子类所重写的最终方法。不可与abstract修饰符同时使用。 abstract该修饰符声明了本方法为抽象类中的抽象方法,必须在非抽象的子类中实现具体操作。不可与final修饰符同时使用。(2)方法的返回值类型可以是基本数值型,也可以是任一引用类型,当没有返回值时,其类型默认为void。(3)形参数列表用于接收方法

84、调用时外界传来的参数,也可以没有参数,但注意的是小括号是不能省略的。每个参数都必须要有自己独立的类型声明,即使相邻的两个参数的类型是相同的也不能公用类型声明,参数之间要用逗号隔开。(4)throws 异常类:其中出现多个异常类时要用逗号隔开。 5.1.4 5.1.4 方法调用及参数传递方法调用及参数传递1 1方法调用方法调用方法根据其是否带有static修饰符可以分为类方法和对象方法(实例方法)。(1)对象方法调用的格式: 对象名方法名(实参列表);(2)类方法调用的格式: 类名方法名(实参列表);没有返回值的方法调用,通常调用的方式比较简单,一般直接构成方法调用语句。 例如:System.o

85、ut.println(“I am a boy!”);例如:int min0;min=Math.min(3,4);2参数传递参数传递(1)形参和实参【例【例5 52 2】程序】程序题题目目public class Test public int min(int a,int b) int c; c=(ab)?a:b; return c; public static void main(String args) int min=0,x=10,y=20; Test t=new Test(); min=t.min(x,y); System.out.println(“min is ”+min); (2 2

86、)值传递)值传递 【例【例5 53 3】程序】程序题题目目/简单类型是用值传递 class Test void method(int i,int j) i = i+10; j = j-10; public class CallByValue public static void main(String args) Test object = new Test(); int a = 25,b = 30; System.out.println(调用前a和b的值: + a + + b); object.method(a,b); System.out.println(调用后a和b的值: + a + +

87、 b); (3 3)引用传递)引用传递【例【例54】程序题目】程序题目/当参数为数组时,传递的方式为引用传递publicclassT2publicstaticvoidmain(Stringargs)inta=1,2,3;method2(a);System.out.println(a0);System.out.println(a1);System.out.println(a2);staticvoidmethod2(inta)a0=0;a1=7;a2=8;【例【例5 55 5】程序题目】程序题目/当参数为对象时,传递的方式为引用传递class Test int a,b; Test(int i,in

88、t j) a = i; b = j; / 传递一个对象 void method(Test ob) ob.a = ob.a+10; ob.b = ob.b-10; public class CallByReference public static void main(String args) Test object = new Test(25,30); System.out.println(调用前object.a和object.b的值: + object.a + + object.b); object.method(object); System.out.println(调用后object.a

89、和object.b的值: + object.a + + object.b); 5.1.5 5.1.5 对象的创建和使用对象的创建和使用1.1.对象声明对象声明类 对象2.2.对象的创建对象的创建(1)先声明对象,再创建对象格式一:格式一:类名 对象变量; 新对象的声明对象变量 = new 类名(参数列表); 新对象内存空间的分配(2)声明对象的同时创建对象格式二:格式二:类名 对象变量 = new 类名(参数列表); 3.3.引用对象的成员变量和调用对象方法引用对象的成员变量和调用对象方法对象.成员变量对象.成员方法(参数列表)aday.year = 2006; /引用对象的成员变量aday.

90、setDate(2006,1,28); /调用对象的方法abcd.equals(abc) 例如:People person1 = new People();People person2 = person1;person1.name = “王明”;4 4thisthis引用引用 this用来访问本类的成员变量和成员方法的引用格式如下: (1)this成员变量 (2)this成员方法(参数列表)一般情况下,在以下几种情况下需要使用到this: 第一,通过this调用另一个构造方法,用法是this(参数列表),这个仅仅在类的构造方法中,别的地方不能这么用。 第二,函数参数或是函数中的局部变量和成员变

91、量同名的情况下,成员变量被屏蔽,此时要访问成员变量则需要用“this.成员变量名”的方式来引用成员变量。 第三,在函数中,需要引用该函所属类的当前对象时候,直接用this。 5 5supersuper引用引用 super用来访问父类的成员变量和成员方法的引用格式有以下几种: (1)super成员变量 (2)super(参数列表) (3)super. 成员方法(参数列表)针对super的引用方式,下面总结一下super的用法: 第一,在子类构造方法中要调用父类的构造方法,用“super(参数列表)”的方式调用,参数不是必须的。同时还要注意的一点是:“super(参数列表)”这条语句只能用在子类构

92、造方法体中的第一行。 第二,当子类方法中的局部变量或者子类的成员变量与父类成员变量同名时,也就是子类局部变量覆盖父类成员变量时,用“super.成员变量名”来引用父类成员变量。当然,如果父类的成员变量没有被覆盖,也可以用“super.成员变量名”来引用父类成员变量,不过这是不必要的。 第三,当子类的成员方法覆盖了父类的成员方法时,也就是子类和父类有完全相同的方法定义(但方法体可以不同),此时,用“super.方法名(参数列表)”的方式访问父类的方法。 【例【例5-65-6】程序题目】程序题目class Personpublic int number;private String name;pr

93、ivate int age;protected void setName(String name)this.name=name;protected void setAge(int age)this.age=age;protected void print()System.out.println(姓名:+name+,年龄:+age); public class DemoSuper extends Personpublic void print()System.out.println(DemoSuper:);super.print();public static void main(String

94、args)DemoSuper test=new DemoSuper();test.setName(张三);test.setAge(20);test.print(); 【例【例5-75-7】程序题目】程序题目class Personpublic static void print(String s) System.out.println(s);Person() print(A Person.); Person(String name) print(A person name is:+name); public class Chinese extends PersonChinese() super

95、();/调用父类构造函数(1)print(A chinese.);/(4)Chinese(String name)super(name);/调用父类具有相同形参的构造函数(2)print(his name is:+name); Chinese(String name,int age)this(name);/调用当前具有相同形参的构造函数(3)print(his age is:+age);public static void main(String args)Chinese people=new Chinese();people=new Chinese(张三);people=new Chines

96、e(张三,20);5.1.6 5.1.6 构造方法及特点构造方法及特点 1 1构造函数构造函数 (1)构造函数1: public Integer(int value) this.value = value; (2)构造函数2 public Integer(String a) throws NumberFormatException this.value = parseInt(s,10); 2 2构造函数的特点构造函数的特点构造方法的使用局限在下述两个地方:(1)创建对象。(2)在构造方法的方法体的第一条语句,可以调用同类中的另一各构造方法或者是父类的构造方法。【例【例5 58 8】程序题目】程

97、序题目 /下面的People类中包含两个构造函数。public class People public String name; public char sex; public int age; public String Idcard; /第一种构造函数,一个不带任何参数和语句的构造函数 public People() /第二种构造函数,带有参数的构造函数 public People(String name,int age,String Idcard) this.name = name; this.age = age; this.Idcard = Idcard;【例【例5 59 9】程序题目

98、】程序题目public class People public String name; public char sex; public int age; public String Idcard; public String getIdcard () return this.Idcard; public String setIdcard (String Idcard) this.Idcard = Idcard; 【例【例5 51010】程序题目】程序题目public class People public String name; public char sex; public int ag

99、e; public String Idcard; public Peple(String name,int age,String Idcard) this.name = name; this.age = age; this.Idcard = Idcard; public String getIdcard () return this.Idcard; public String setIdcard (String Idcard) this.Idcard = Idcard; 【例【例5 51111】程序题目】程序题目 /例题510修改如下public class People public Str

100、ing name; public char sex; public int age; public String Idcard; public People() public People(String name,int age,String Idcard) this.name = name; this.age = age; this.Idcard = Idcard; public String getIdcard () return this.Idcard; public String setIdcard (String Idcard) this.Idcard = Idcard; 5.1.7

101、 5.1.7 对象的初始化对象的初始化初始化的四个要点,如下:1如果有static,即静态成员定义,首先初始化static的变量。2static只初始化一次,在第二次创建类的对象的时候,就不会去执行static的语句。3变量的初始化在方法前。4在含有main的类中执行顺序是先做static,然后就是main,而不是像其它类一样,除了static就按顺序做下来。 5.2 5.2 任务二任务二 掌握类的封装掌握类的封装 5.2.1 5.2.1 访问权限访问权限访问控制符的修饰范围名称修饰符本类子类包所有类公共public可见可见可见可见私有private可见受保护protected可见可见可见友好

102、可见可见注意:注意:(1)默认修饰符为friend类,但在Java语言中,friend不是关键字。所以在默认情况下,成员的访问范围只在本类和本包当中,其子类和其它类是不能访问的。(2)修饰符protected仅仅用于继承情况下。(3)当一个类成员的修饰符为public时,说明该成员可以被程序中任何其它代码访问。(4)当一个类成员的修饰符为private时,则该成员只能它自身类的其它成员访问。访问控制符要放在成员类型的其他说明之前,也就是说,成员的声明语句必须以访问控制符开头。 【例【例5 51212】程序题目】程序题目class Test1 int a;public int b; privat

103、e int c; void setc(int i) c = i; int getc() return c;class Test2 public static void main(String args) Test1 object = new Test1();object.a = 10;object.b = 20;/ object.c = 100; / Error!object.setc(100);System.out.println(a,b,and c: + object.a + +object.b + + object.getc();5.2.2 5.2.2 类变量和实例变量类变量和实例变量

104、1类变量类变量类变量也称为静态变量,由static修饰,如:staticintage;age就是类变量,它只能通过类来访问。类变量的访问格式不同于一般的实例变量。类变量的访问格式:类变量的访问格式:类名变量名类名变量名【例【例5 51313】程序题目】程序题目/下面的例子说明了类变量b在它的类之外如何被访问。class Demo static int a = 42; static int b = 99; void callme() System.out.println(a = + a); public class StaticByName public static void main(Str

105、ing args) Demo ob=new Demo();ob.callme();System.out.println(b = + Demo.b); 2 2实例变量实例变量【例【例5 51414】程序题目】程序题目public class People public String name; public char sex; public int age; public String Idcard; /空构造方法 public People() /带三个参数的构造方法 public People(String name,int age,String Idcard) this.name = na

106、me; this.age = age; this.Idcard = Idcard; public static void main() People p1=new People(); People p2=new People(); 3 3类变量和实例变量的区别类变量和实例变量的区别(1)实例变量没有static修饰符,它只能通过实例对象来访问,而类变量则直接通过类名来访问。(2)同一类的不同的实例对象有自己的实例变量,但是它们共享同一个类变量。当一个实例对象修改了它的实例变量时,不会影响其他的实例对象。但当一个实例对象修改了类变量时,则会影响其他的对象实例。而类变量则是一变全变。(3)类变量要

107、在使用前进行初始化,实例变量则不需要。5.2.3 5.2.3 类成员方法和函数数学方法类成员方法和函数数学方法1 1类成员方法类成员方法 类方法的调用格式:类方法的调用格式:类名方法名(实参列表)类名方法名(实参列表) 【例【例515】程序题目】程序题目publicclassExamplepublicstaticvoiddisplay()System.out.println(类的方法);publicvoiddisplayOne()System.out.println(对象的方法);publicstaticvoidmain(Stringargs)Example.display();Example

108、e=newExample();e.displayOne();类方法体有以下限制,一旦违反将导致编译错误:(1)类方法中不能引用对象变量(2)类方法中不不调用类的对象方法(3)在类方法中不能使用super、this关键字。2 2函数数学方法函数数学方法 sin(arg)cos(arg)tan(arg)asin(arg)acos(arg)atan(arg)atan2(arg1,arg2)正弦余弦正切余切反余弦反正切2个参数的反正切abs(arg)计算参数的绝对值max(arg1,arg2)返回较大一个ceil(arg)返回大于等于该参数的最小整数floor(arg)返回小于等于该参数的最大整数ro

109、und(arg)计算于参数值最接近的整数(参数floor或double)rint(arg)计算于参数值最接近的整数(参数double)min(arg1,arg2)返回小的一个IEEEremainder(art1,arg2)计算arg1除以arg2得到的余数sqrt(arg)求参数平方根cbrt(arg)求参数立方根pow(arg1,arg2)计算以arg1为底数,以arg2为指数的冥hypot(arg1,arg2)计算arg1和arg2的平方根exp(arg)计算e为底数以arg为指数的冥expm1(arg)计算e为底数以arg为指数的冥并减1log(arg)计算参数的自然对数log1p(ar

110、g)计算arg+1的自然对数log10(arg)计算参数的底数为10的对数random()返回一个大于0.0并且小于1.0的伪随机数(较常用)5.3 项目实战一 类和对象1.实战内容定义一个Person类,可以在应用程序中使用该类。要求具有:成员属性:Person类的属性(变量): 姓名:name,字符串类型:String; 性别:sex,字符型:char; 年龄:age,整型:int。3个构造函数: public Person(String s) /设置姓名 public Person(String s,char c) /调用本类的构造函数 Person(String s),设置性别 pub

111、lic Person(String s,char c,int i)/调用本类的构造函数PersonPerson(String s,char),设置年龄一个成员方法: public String toString()/获得姓名、性别和年龄利用定义的Person类,请实例化对象,输出下面结果:姓名:张三 性别:男 年龄:212.实战目的 通过实战,掌握类的定义方法;实例化对象。3.实战过程程序代码如下:public class Person private String name; private char sex; private int age; public Person(String s)

112、 name = s;publicname = s;sex = c;public Person(String s,char c,int i)name = s;sex = c;age = i;public String toString()if(sex=M)|(sex=m)return 姓名:+name+ 性别:男+ 年龄:+age;else if(sex= W)|(sex=w)return 姓名:+name+ 性别:女+ 年龄:+age;elsepublic static void main(String args)Person p1=new Person(张三,M,21);System.out

113、.println(p1.toString();项目小结 本项目重点介绍了定义和使用类的基础知识。类是对象的蓝图或模型,它定义了对象的行为和属性。(1)类的定义类的三要素:类名、属性和方法。定义一个类包含3个步骤:属性声明、构造方法的定义和成员方法的定义。在定义完类之后要对数据进行初始化。若在类的属性和方法声明中使用了static修饰符,则说明该属性和方法是类属性和类方法,供本类的所有对象共享;没有被static修饰的属性和方法则只属于基于该类创建的某个对象。 (2)对象 对象是类的实例,它的生命周期包括从对象被创建到对象的消亡,在这段时间它在内存中占有一定的空间。 每个对象都具有:对象变量名;

114、对象的状态;对象的行为,通常把它称为方法,通过它所接收的消息来定义。 读者需要重点掌握的是构造方法的作用。 类的方法声明中的this只有在运行中才与一个具体的对象联系,指向包含该方法体的对象。项目6 类的继承与多态 任务一 掌握类的继承任务二 掌握类的多态任务三 掌握接口的使用任务四 掌握包的使用项目实战一 继承编程项目实战二 多态编程6.1 6.1 任务一任务一 掌握类的继承掌握类的继承 继承:子类拥有父类的属性和方法继承:子类拥有父类的属性和方法我们通过一个实际应用问题来引出类的继承这个问题的讲解。我们通过一个实际应用问题来引出类的继承这个问题的讲解。6.1.1 继承的基本概念 【例【例6

115、-1】定义一个普通人的】定义一个普通人的类和学生类。类和学生类。public class Person public String name;public int age;public String getInfo().public class Student public String name ;public int age;public String school;public String getInfo().public String study().Student类中包含了Person类的所有属性和方法。针对这种情况,Java引入了继承这个概念,只要表明类Student继承了类Pe

116、rson的所有属性和方法,就不用在类Student中重复书写类Person中的代码了,更确切的说就是简化了类的定义。我们通过extends关键字来表明类Student 具有类Person的说有属性和方法 上面的两个类可以简写成下面的代码:【例6-2】简写的学生类。public class Person public String name;public int age;public String getInfo().public class Student extends Personpublic String school;public String study().在类的继承中有这样一些细

117、节问题:1.通过继承可以简化类的定义,可以实现代码重用,在上面的例子中我们重用了基类的属性和方法。2.Java只支持单继承,不允许多重继承。也就是说,在Java中一个子类只能有一个父类,不允许一个类直接继承多个父类,但一个类可以被多个类继承。3.Java中可以有多层继承。即一个类可以继承为某一个类的子类。如类Y继承了类X,类Z又可以继承类Y,那么类Z也间接继承了类X。这种应用如下所示:class X class Y extends X class Z extends Y4.子类继承父类所有的成员变量和成员方法,但不继承父类的构造方法。在子类的构造方法中可以使用super(参数列表)调用父类的构

118、造方法。如: public class Student extends Personpublic Student(String name,int age,String school)super(name,age);this.school=school;5.如果子类的构造方法中没有显示的调用父类的构造方法,也没有使用this关键字调用重载其他的构造方法,则在产生之类的实例对象时,系统默认调用父类无参数的构造方法,也就是说在下面的的类B中定义的构造发昂法中,写不写super()语句效果是一样的。public class B Person A public B() super();/有没有这一句,效

119、果都是一样的 public class Student extends Person public void study() System.out.println(学习中.);public static void main(String args) Person p = new Person();p.name = 张三;p.age = 35;p.getInfo();Student s = new Student();s.name = 李四;s.age = 18;s.getInfo();s.study();6.1.2 继承的实现对象中的成员变量的初始化过程是按照下述步骤进行的:1.分配成员变量的

120、存储空间并进行默认的初始化,就是用new关键字产生对象后,对类中的成员变量进行初始化赋值。2.绑定构造方法参数,就是new Person(实际参数列表)中所传递的参数赋值给构造方法中的形式参数变量。3.如果有this()调用则调用相应得重载构造方法(被调用的重载构造方法又从步骤(2)开始执行这些流程),被调用的重载构造方法执行流程结束后,回到当前构造方法当前构造方法直接跳到步骤(6)执行。4.显式或隐式追溯调用父类的构造方法(一直到Object类为止,Object是所有Java类的最顶层父类),父类的构造方法又从步骤(2)开始对父类执行这些流程,父类的构造方法执行流程结束后,回到当前的构造方法

121、,当前的构造方法继续执行。5.进行实例变量的显示初始化操作,也就是执行在定义成员变量是就对其进行赋值的语句,如:public class Student extends PersonString school=HRBJZ/显式初始化.将HRBJZ赋值给school成员变量6.执行当前构造方法中方法体中的程序代码,如:public class Student extends Personpublic Student(String name,int age,String school)super(name,age);this.school=school;6.1.3 super与this的使用1.t

122、his:使用在一个成员函数的内部,指向当前对象 【例6-4】使用this变量访问对象的成员变量。class Person String name; int age; void Person(String name,int age)this.name=name;this.age=age;this用来访问本类的成员变量和成员方法的引用格式如下:(1)this成员变量(2)this成员方法(参数列表)一般情况下,在以下几种情况下需要使用到this:1通过this调用另一个构造方法,用法是this(参数列表),这个仅仅在类的构造方法中,别的地方不能这么用。2函数参数或是函数中的局部变量和成员变量同名的

123、情况下,成员变量被屏蔽,此时要访问成员变量则需要用“this.成员变量名”的方式来引用成员变量。3在函数中,需要引用该函所属类的当前对象时候,直接用this。this还有一个用法,就是构造函数的第一个语句,它的形式是this(参数表),这个构造函数就会调用同一个类的另一个相对的构造函数。 【例6-5】this的另一用法。class UserInfopublic UserInfo(String name) this(name,aNewSerialNumber);public Userinfo(String name,int number)userName=name;userNumber=numb

124、er;2 2supersuper引用引用super是用在子类中,目的是访问直接父类(即类之上最近的超类)中被屏蔽的成员。【例6-6】super的用法示例class Personpublic int number;private String name;private int age;protected void setName(String name)this.name=name;protected void setAge(int age) this.age=age;protected void print()System.out.println(姓名:+name+,年龄:+age); pub

125、lic class DemoSuper extends Personpublic void print()System.out.println(DemoSuper:);super.print();public static void main(String args)DemoSuper test=new DemoSuper();test.setName(张三);test.setAge(20);test.print();【例【例6-76-7】在对象初始化的时候自动调用this和super: class Personpublic static void print(String s)System.

126、out.println(s); Person()print(A Person.);Person(String name)print(A person name is:+name);public class Chinese extends PersonChinese()super();/调用父类构造函数(1)print(A chinese.);/(4)Chinese(String name)super(name);/调用父类具有相同形参的构造函数(2)print(his name is:+name); Chinese(String name,int age)this(name);/调用当前具有相

127、同形参的构造函数(3)print(his age is:+age);public static void main(String args)Chinese people=new Chinese();people=new Chinese(张三);people=new Chinese(张三,20);综上所述,super用来访问父类的成员变量和成员方法的引用格式有以下几种:(1)super成员变量(2)super(参数列表)(3)super. 成员方法(参数列表)针对super的引用方式,下面总结一下super的用法:第一,在子类构造方法中要调用父类的构造方法,用“super(参数列表)”的方式调用

128、,参数不是必须的。同时还要注意的一点是:“super(参数列表)”这条语句只能用在子类构造方法体中的第一行。第二,当子类方法中的局部变量或者子类的成员变量与父类成员变量同名时,也就是子类局部变量覆盖父类成员变量时,用“super.成员变量名”来引用父类成员变量。当然,如果父类的成员变量没有被覆盖,也可以用“super.成员变量名”来引用父类成员变量,不过这是不必要的。第三,当子类的成员方法覆盖了父类的成员方法时,也就是子类和父类有完全相同的方法定义(但方法体可以不同),此时,用“super.方法名(参数列表)”的方式访问父类的方法。6.1.4 final类和final方法1.final标记的类

129、不能被继承。2.final标记的方法不能被子类重写。3.final标记的变量(成员变量和局部变量)成为常量,只能赋值一次。如:final int Y=2;Y=3;/出错4.final标记的成员变量必须在声明的同时显式赋值,或在该类的构造方法中显式赋值,然后才能使用,如:class Testfinal int X=5;或者:class Testfina int X;Test()X=3;5.方法中定义的内置类只能访问该方法内的final类型的局部变量,用final定义的局部变量相当于是一个常量,它的生命周期超出方法运行的生命周期。6.将一个形式参数定义成final也是可以的,这就限定了我们在方法中

130、修改形式参数的值。7.final标记的变量(成员变量或局部变量)通常我们称为常量,只能赋值一次,但这个“常量”也只能在这个类的内部使用,不能在类的外部直接使用。但当我们用public static final共同标记常量时,这个常量就成为了全局常量,而且这样定义的常量只能在定义时赋值,即使在构造函数里面也不能对其进行赋值,如:class Personpublic static final String name=张三;. 6.2 任务二任务二 掌握类的多态掌握类的多态 在Java中我们通过方法的重载和方法的覆盖(重写)来实现了多态性,下面本节我们通过介绍方法的重载和覆盖来给大家介绍Java是如

131、何实现多态的。6.2.2 6.2.2 方法的重载方法的重载1.成员函数的重载【例6-8】方法重载的例子:/方法的重载.classOverloadDemo/不含参数voidtest()System.out.println(Noparameters);/含有一个整型参数.voidtest(inta)System.out.println(a:+a);/含有两个整型参数voidtest(inta,intb)System.out.println(aandb:+a+b);/含有一个双精度型参数doubletest(doublea)System.out.println(doublea:+a);returna

132、*a;publicclassOverloadpublicstaticvoidmain(Stringargs)OverloadDemoob=newOverloadDemo();doubleresult;/ 调用各种类型的参数test()ob.test();ob.test(10);ob.test(10,20);result = ob.test(123.25);System.out.println(Result of ob.test(123.25): + result);2.构造函数重载 除了重载正常的方法外,构造函数也能够重载。实际上,对于大多数你创建的现实的类,重载构造函数是很常见的,并不是什么

133、特例。为了理解为什么会这样,我们给出一个Box类的例子:【例6-10】Box类重载的例子。classBoxdoublewidth;doubleheight;doubledepth;/该类的构造函数Box(doublew,doubleh,doubled)width=w;height=h;depth=d;/返回体积doubulevolume()returnwidth*height*depth;下面程序是Box的一个改进版本,它就是运用对Box构造函数的重载来解决这些问题的:classBoxdoublewidth;doubleheight;doubledepth;/包含所有参数Box(doublew

134、,doubleh,doubled)width=w;height=h;depth=d; /没有参数的特殊盒子Box()width=-1;height=-1;depth=-1;/用-1表示未初始化的盒子/立方体盒子。只有一个参数Box(doublelen)width=height=depth=len;/返回体积doublevolume()returnwidth*height*depth;public class OverloadCons public static void main(String args) / 创建给出不同参数个数的盒子Box mybox1 = new Box(10,20,15

135、);Box mybox2 = new Box();Box mycube = new Box(7); double vol; vol = mybox1.volume();System.out.println(Volume of mybox1 is + vol); vol = mybox2.volume();System.out.println(Volume of mybox2 is + vol);vol = mycube.volume();System.out.println(Volume of mycube is + vol);6.2.3 6.2.3 方法的覆盖方法的覆盖1.1.方法覆盖方法覆

136、盖在子类中根据需要对父类中继承来的方法进行改造方法的覆盖(也叫重写)。覆盖方法必须和被覆盖的方法具有相同的方法名称、参数列表和返回值类型。【例6-11】修改后的Student类和Person类重写了getInfo()方法:class Personpublic String name;public int age;public Person(String name,int age) this.name=name;this.age=age;public Person() public void getInfo()System.out.println(name);System.out.println

137、(age);public class Student extends Personpublic String school;public void study()System.out.println(学习中.);public void getInfo()super.getInfo();System.out.println(school);public static void main(String args)Person p=new Person();p.name=张三;p.age=35;p.getInfo();Student s=new Student();s.name=李四;s.age=1

138、8;s.school=哈尔滨金融高等专科学校;s.getInfo();s.study();(1)(1)子类型转换成父类子类型转换成父类【例6-12】子类型B转换成父类A。class Apublic void func1()System.out.println(A function is calling);public void func2()func1(); class B extends Apublic void func1()System.out.println(B function is calling);public void func3()System.out.println( B

139、func3 is calling);2.父类对象与子类对象之间的转换父类对象与子类对象之间的转换public class cpublic static void main(String args)B b=new B();A a=b;callA(a);callA(new B();public static void callA(A a)a.func1();a.func2();(2)(2)父类转换成子类父类转换成子类【例6-13】父类型转换成子类。public static void CallA(A a)B b=(B)a;b.func1();b.func2();b.func3();(3)insta

140、nceof(3)instanceof操作符操作符可以用instanceof判断是否一个类实现了某个接口,也可以用它对一个实例对象是否属于一个类。instanceof语法格式为:对象 instanceof 类(或接口)它的返回值是布尔型的,或为true,或者为false【例6-14】instanceof操作符的使用。public static void CallA(A a) if (a instanceof B)B b=(B)a;b.func1();b.func2();b.func3();elsea.func1();a.func2();6.3任务三掌握接口的使用6.3.1 抽象类和抽象方法抽象类

141、和抽象方法Java中可以定义一些不含方法体的方法,它的方法体的事项交给该类的子类根据自己的情况去实现,这样的方法就是抽象方法,包含抽象方法的类就叫抽象类.一个抽象类中可以有一个或多个抽象方法。抽象类定义规则:1.抽象类必须用abstract关键字来修饰; 抽象方法也必须用abstract来修饰。2.抽象类不能被实例化,也就是不能用new关键字去产生对象。3.抽象方法只需要声明,不需要去实现。4.含有抽象方法的类不许被声明为抽象类,抽象类的子类也必须覆盖收有抽象方法后才能被实例化,否则这个子类还是一个抽象类。抽象方法的写法abstract 返回值类型 抽象方法(参数列表)例:abstract c

142、lass Aabstract int xx(int x,int y);含有抽象方法的类肯定是抽象类,抽象类中的某个方法不一定是抽象的。6.3.2 接口的声明如果一个抽象类中的所有方法都是抽象的,就可以将这个类用另外一种方式来定义,也就是接口定义。接口是抽象方法和常量值的定义的集合。例:public interface Runner int ID=1001;void run();6.3.3 接口的使用我们可以定义一个新的接口用extends关键字去继承已有的接口;也可以定义一个类,用implements关键字去实现一个接口中的所有方法;还可以定义一个抽象类,用implements关键字去实现一个

143、接口中定义的部分方法。【例6-15】接口和抽象类的定义和使用。interface Animal extends Runnervoid breathe();class Fish implements Animalpublic void run()System.out.println(fish is swimming.);public void breathe()System.out.println(fish is bubbling.);abstract class LandAniamal implements Animalpublic void breathe()System.out.print

144、ln(LandAnimal is breaching.);6.4 任务四 掌握包的使用6.4.1 包的概念包是java语言提供的组织类和接口的工具,即包是一组相关类和接口的集合。包的定义(四步) 1、创建一个文件夹,文件夹名与包名相同。 2、构建包: package 包名; /必须是第一条语句/ 类的定义; /存盘时以类名保存为.java文件/ 3、对保存的文件进行编译,产生.class文件。 4、将.class文件放入第一步建立的与包名同名的文件夹中。该文件夹即是包。 注意:包名全部用小写字母。【例6-16】包的定义。package edu.hrbjzpublic class Testpac

145、kage public static void main(String args) new Test().print;class Testpublic void print()System.out.println( Teaching how to using package!);6.4.2 包的使用【例6-16】包的使用。package edu.hrbjzpublic class Testpackage public static void main(String args) new Test().print; /标记程序清单2:Test.javapackage edu.hrbjz.examp

146、le;class Testpublic void print()System.out.println( Teaching how to using package!);6.4.3 常用系统包1.java.lang包:java的核心类库,包含了运行java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省加载这个包。这里需要补充说明的的是这个java.lang包从java1.2版本以后对于其中的类,不需要实用import语句来做导入了,如我们前面经常使用的System类。2.java.io包:java语言的标准输入/输出类库,如基本输入/输出流、文件输入

147、/输出、过滤输入/输出流等等。3.java.util包:包含如处理时间的date类,处理变成数组的Vector类,以及stack和HashTable类。4.java.util.zip包:实现文件压缩功能。5.java.lang.reflect包:提供用于反射对象的工具。6.java.awt.image包:处理和操纵来自于网上的图片的java工具类库。7.java.wat.peer包:很少在程序中直接用到,使得同一个java程序在不同的软硬件平台上运行。包:实现网络功能的类库有Socket类、ServerSocket类9. ava.awt.event包:GUI事件处理包。10.java.sql包

148、:实现JDBC的类库。11.java.awt.datatransfer包:处理数据传输的工具类,包括剪贴板,字符串发送器等。12.java.awt包:构建图形用户界面(GUI)的类库,低级绘图操作Graphics类,图形界面组件和布局管理如Checkbox类、Container类、LayoutManger接口等,以及界面用户交互控制和事件响应,如Event类。65 项目实战一 继承编程1.实战内容 创建一个项目,在项目中创建Subroutine类和两个内部类,分别为Parent和SubParent。这3个类的继承关系是Subroutine类继承 SubParent类,而SubParent类继承

149、Parent类。分别在这3个类的构造方法中输出构造方法名称,然后创建Subroutine类的实例对象,继承机制将使该类的父类对象自动初始化。2.实战目的 掌握实现继承的方法;3.实战过程程序代码如下:class Parent / 父类Parent() System.out.println(调用父类的parent()构造方法);class SubParent extends Parent / 继承Parent类SubParent() System.out.println(调用子类的SubParent()构造方法);public class Subroutine extends SubParent

150、 / 继承SubParent类Subroutine() System.out.println(调用子类的Subroutine()构造方法);public static void main(String args) Subroutine s = new Subroutine(); / 实例化子类对象66 项目实战二 多态编程1.实战内容 利用多态求面积,当只有一个参数时,求圆的面积;两个参数时,求矩形的面积;三个参数时,求三角形的面积。2.实战目的 掌握多态编程的方法;3.实战过程程序代码如下:import java.math.*;class 面积double s,l;String o;面积(i

151、nt a)o=圆形;s=3.14*a*a;面积(int a,int b)o=矩形;s=a*b;面积(int a,int c,int b)o=三角形;if(a+bc&a+cb&b+ca)l=(a+b+c)/2;s=Math.sqrt(l*(l-a)*(l-b)*(l-c);void speak()System.out.println(o+的面积为:+s);public class area public static void main(String args) 面积 x=new 面积(5);x.speak();面积 y=new 面积(4,5);y.speak();面积 z=new 面积(4,5

152、,3);z.speak();项目小结 继承是一种由已有的类创建新类的机制。利用继承,可以先创建一个共有属性的一般类,再根据该一般类创建具有特殊属性的新类。Java只支持单继承,不允许多重继承。 多态是面向对象编程的一个重要特性。子类可以体现多态,即子类可以根据各自的需要重写父类的某个方法,子类通过方法的重写可以把父类的状态和行为改变为自身的状态和行为。接口也可以体现多态,即不同的类在实现同一接口时,可以给出不同的实现手段。/ 网卡class SoundCard implements PCI public void start() System.out.println(声卡开启.啦啦啦.);pu

153、blic void stop() System.out.println(关闭声卡!);/ 声卡class MainBoard public void usePCICard(PCI p) p.start();p.stop();/ 主板调用接口的运行方法,也就是调用PCI的函数public class Assembler public static void main(String args) MainBoard mainBoard = new MainBoard();NetworkCard networkCard = new NetworkCard();mainBoard.usePCICard(

154、networkCard);SoundCard sc = new SoundCard();mainBoard.usePCICard(sc);本章小结本章小结 通过本章的学习,读者能够掌握在Java语言中实现继承和多态,能够掌握对类的重载和重写,并且能够通过接口来实现多态。同时本章也介绍了包的使用以及JDK自带的部分系统包。项目7 异常处理和多线程 任务一 掌握Java中对异常的处理任务二 掌握程序对多线程的处理项目实战一 异常处理编程项目实战二 多线程编程 7.1 7.1 任务一任务一 掌握掌握JavaJava中对异常的处理中对异常的处理7.1.1 异常类和异常处理机制异常类和异常处理机制1.

155、异常类异常类 Java语言采用面向对象的方法来处理异常,每个异常都是由异常类产生的对象,所有的异常类(java.lang.Exception)均继承自java.lang.Object中的java.lang.Throwable类。它提供了一些方法让我们能够了解异常产生的原因和一些相关的信息。Java中的异常类具有层次组织,Throwable类是Object类的直接子类,Throwable类又有Error类(错误类)和Exception类(异常类)两个直接子类,这两个子类又有许多各自的子类,如图7-1。图7-1异常类的继承结构2. 异常处理机制异常处理机制Java语言提供的异常处理机制,由捕获异常

156、和处理异常两部分组成。在Java程序的执行过程中,如果出现了异常事件,就会生成一个异常对象。生成的异常对象将传递给Java运行系统,这一异常的产生和提交过程称为抛出(throw)异常。当Java系统得到一个异常对象时,它将会寻找处理这一异常的代码。找到能够处理这种类型的异常的方法后,系统把当前异常对象交给这个方法进行处理,这一过程称为捕获(catch)异常。如果Java运行时系统找不到可以捕获异的方法,则运行时系统将终止,相应的Java程序也将退出。7.1.2 7.1.2 程序中异常处理方法程序中异常处理方法 1. 1. 捕获异常捕获异常 在在JavaJava中用中用try-catch- fi

157、nallytry-catch- finally结构来捕获和处结构来捕获和处理异常,其语法结构理异常,其语法结构为: try可能产生异常的程序代码块;catch()/要处理的第一种异常处理捕获到的异常的代码块;catch()/要处理的第二种异常处理捕获到的异常的代码块;finally /最终处理语句无论是否抛出异常都要执行的代码; 说明:说明: try后面的用来选定捕获异常的范围,就是我们觉得哪段语句可能会出现异常我们就把这部分语句放到try后面的里,如果这一范围内的某条语句发生异常,程序就会跳出try部分,不再继续try块中剩余的语句,根据异常的类型来执行相应的catch语句块,去处理相应的异

158、常。catch语句可以有多个,构成多重catch语句,处理不同类型的异常。如果有一个catch语句指定的异常类型与发生的异常类型相符,那么就会执行这个catch语句,其他的catch语句则会被跳过不被执行。如果没有抛出异常,那么try代码块就会结束,并且会跳过所有catch语句,从最后一个catch后面的第一个语句继续执行。因此,只有在有异常抛出时,才会执行catch语句。catch语句中定义变量的方法与在方法中定义参数相同,只不过这个变量对应的是一个对象实例。不论前面catch语句执不执行finally后面中的语句都会执行。【例【例7-37-3】加入异常处理的多异常程序】加入异常处理的多异常

159、程序importimport javax.swing.JOptionPane;publicpublic classclass ArrayTest2 staticstatic voidvoid arraylong() intint inputvalue,i;String input;intint array;dodoinput=JOptionPane.showInputDialog(请输入数组长度:);/ 显示输入对话框inputvalue=Integer.parseInt(input);/将输入的数据转换为整型trytryarray=newnew intintinputvalue;forfor

160、(i=0;i5;i+)System.out.println(输出array+i+=+arrayi+ i=+i);catchcatch(NegativeArraySizeException e)JOptionPane.showMessageDialog(nullnull,数组长度不能为负数请重新输入);/输出异常处理信息catchcatch(ArrayIndexOutOfBoundsException f)JOptionPane.showMessageDialog(nullnull,数组长度越界请重新输入);whilewhile(inputvalue5);/条件不符合时返回重新输入JOption

161、Pane.showMessageDialog(nullnull,数组长度是+inputvalue,数组长度是,JOptionPane.INFORMATION_MESSAGE);publicpublic staticstatic voidvoid main(String args) Arraylong(); 【例【例7-3】执行结果】执行结果2 2. . 异常的捕获顺序异常的捕获顺序 在程序中捕获的在程序中捕获的NegativeArraySizeExceptionNegativeArraySizeException异常类和异常类和ArrayIndexOutOfBoundsExceptionArr

162、ayIndexOutOfBoundsException异常类都是异常类都是ExceptionException的子类,然而父子的子类,然而父子类之间是可以有自动类型转换运算的,这就导致了异常捕获时有先后顺序,类之间是可以有自动类型转换运算的,这就导致了异常捕获时有先后顺序,如果我们将如果我们将catch(NegativeArraySizeException e)catch(NegativeArraySizeException e)改为改为catch(Exception catch(Exception e)e),当产生,当产生ArrayIndexOutOfBoundsExceptionArray

163、IndexOutOfBoundsException异常时第一个异常时第一个catchcatch就会先将就会先将这个异常捕获并转换为这个异常捕获并转换为ExceptionException,后一个,后一个catchcatch就不起作用了,程序就会报就不起作用了,程序就会报错如图错如图7-57-5。 图7-5需要指出的是Java系统本身给我们提供了几种显示信息的方法如:toString()方法会显示异常类的名称和产生的原因。getLocalizedMessage()方法和getMessage()方法会显示异常发生的原因但不会显示异常的名称。其中getLocalizedMessage()方法显示的信

164、息会以该程序所在平台的语系所使用的文字为主。printStackTrace()方法会显示产生这个异常的相关类名称以及是第几行程序代码产生的这个异常。3. 3. 抛出异常抛出异常(1 1)throwsthrows关键字的使用关键字的使用在方法中声明使用在方法中声明使用throwsthrows的具体格式为:的具体格式为:返回类型返回类型 方法名(参数方法名(参数1 1,参数,参数2 2)throwsthrows异常类型异常类型1 1,异常,异常类型类型22 返回类型是方法的返回数据类型,参数是方法的参数,异常返回类型是方法的返回数据类型,参数是方法的参数,异常类型可以有多个用逗号隔开。我们可以将例

165、类型可以有多个用逗号隔开。我们可以将例7-37-3中在中在arraylongarraylong()()方法中可能出现的异常抛出,由调用它的方法中可能出现的异常抛出,由调用它的main()main()方法来处方法来处理。理。【例【例7-47-4】声明抛出异常程序】声明抛出异常程序import javax.swing.JOptionPane;public class ArrayTest3 static void arraylong()throws NegativeArraySizeException,ArrayIndexOutOfBoundsException int inputvalue,i;S

166、tring input;int array;array=new int5; input=JOptionPane.showInputDialog(请输入数组长度(必须为小于5的正整数):);inputvalue=Integer.parseInt(input);for(i=0;i100)throw new ZiDing(a);/抛出自定义类System.out.println( a +是合法操作数);System.out.println( 程序结束);public static void main(String args)tryjiancha(50);jiancha(101);catch (ZiD

167、ing e)/捕获自定义类System.out.println(捕获了异常 + e);7.2.1 7.2.1 多线程的概念多线程的概念 多多线线程程是是相相对对于于单单线线程程而而言言的的,指指的的是是在在一一个个程程序序中中可可以以定定义义多多个个线线程程并并同同时时运运行行它它们们,每每个个线线程程可可以执行不同的任务。以执行不同的任务。 多多线线程程的的意意义义在在于于一一个个应应用用程程序序的的多多个个逻逻辑辑单单元元可可以以并并发发地地执执行行。但但是是多多现现程程并并不不意意味味着着多多个个用用户户进进程程在在执执行行,操操作作系系统统也也不不把把每每个个线线程程作作为为独独立立的

168、的进进程程来来分配独立的系统资源。分配独立的系统资源。 进程之间切换系统开销大,线程之间切换开销小。进程之间切换系统开销大,线程之间切换开销小。7.2 任务二掌握程序对多线程的处理任务二掌握程序对多线程的处理7.2.2 7.2.2 实现多线程的两种方法实现多线程的两种方法 我们有两种方法来实现多线程,一种方法是从Thread类继承,写一个Thread类的子类,在子类中重写run()方法覆盖掉Thread类中的run()方法,每个线程都是通过某个特定Thread对象的run( )方法来完成其操作的,run( )方法称为线程体。线程所要运行的程序代码就是run()方法中的程序代码,格式为:clas

169、s类名 extends Threadpublic void run()方法体【例【例7-7-17-7-1】继承】继承ThreadThread类类public static class Thread1 extends Thread public static class Thread1 extends Thread public void run() public void run() System.out.println(A); System.out.println(A); 另一种方法是提供一个实现接口Runnable的类作为一个线程的目标对象,在初始化一个Thread类或者Thread子类的

170、线程对象时,把目标对象传递给这个线程实例,由该目标对象提供线程体 run()格式为:class 类名 implements Runnable public void run() 方法体【例【例7-7-27-7-2】实现】实现RunnableRunnable接口接口public static class Thread2 implements Runnable public void run() System.out.println(1); 说明:说明: 这两种构造线程体方法各有优缺点,使用Runnable接口可以将CPU、代码和数据分开,形成清晰的模型,还可以从其他类继承。 直接继承Thread

171、类时,由于Java不支持多重继承所以不能再从其他类继承,但编写简单可以直接操纵线程。 7.2.3 7.2.3 线程的生命周期和线程的控制线程的生命周期和线程的控制1. 1. 线程的生命周期线程的生命周期线程的生命周期可以分为5种状态:创建状态(new Thread)、可运行状态( Runnable )、运行状态(Running )、阻塞态(Blocked)、死亡状态(Dead)。 2. 线程的控制线程的控制 线程的控制主要是通过线程的控制主要是通过Thread中提供的线程状态转换的方中提供的线程状态转换的方法实现的。法实现的。 (1)start()方法方法start()方法使新生成的线程实体从

172、新生状态转入可运行状态,方法使新生成的线程实体从新生状态转入可运行状态,如:如: Thread A=new Thread(); A.start();需要说明的是,一个需要说明的是,一个thread对象只能调用一次对象只能调用一次strat方法,如果方法,如果对一个已经启动的线程再调用对一个已经启动的线程再调用start方法就会产生异常。方法就会产生异常。 (2)sleep()方法方法 从从sleep()方法的名字上就可以看出这个方法是让线程对象睡方法的名字上就可以看出这个方法是让线程对象睡一会觉,想让线程对象睡多长时间我们只需把时间参数传入就一会觉,想让线程对象睡多长时间我们只需把时间参数传入

173、就可以了,只不过这个参数是以千分之一秒为单位的,如果想停可以了,只不过这个参数是以千分之一秒为单位的,如果想停一秒钟,就要输入一秒钟,就要输入1000。sleep()方法有两种格式方法有两种格式sleep(long millis)和和 sleep(long millis,int nanos),nanos为附加时间单位为为附加时间单位为纳秒。当运行纳秒。当运行sleep()方法后线程就会暂停相应的时间,当暂停方法后线程就会暂停相应的时间,当暂停的时间到了以后,线程会转入可运行状态等待运行,而不是直的时间到了以后,线程会转入可运行状态等待运行,而不是直接进入运行状态,传入的时间参数只是保证线程对象

174、至少会停接进入运行状态,传入的时间参数只是保证线程对象至少会停止的时间。止的时间。需要指出的是在线程暂停过程中可能遇到外部中断异常,导致需要指出的是在线程暂停过程中可能遇到外部中断异常,导致程序中断,所以需要进行异常处理。程序中断,所以需要进行异常处理。【例【例7-9】start()方法与方法与sleep()方法应用程序方法应用程序public class SleepTest extends Thread String light ; SleepTest(String light)this.light=light; public void run()tryfor(int i=1;i=5;i+)

175、System.out.println(light+i+次次); sleep(100);catch(Exception e)System.err.print(e); public static void main(String args) new SleepTest(1号灯亮号灯亮).start(); new SleepTest(2号灯亮号灯亮).start();(3)yield()方法yield()方法使当前进程放弃运行,进入到可运行状态,重新排队等待运行,给其他可运行的进程一个运行的机会,但并不是一定就会轮到其他的线程运行,因为如果优先级相同调用yield()方法的线程有可能又被选中获得执行

176、的机会,我们可以把例7-9中的sleep()换成yield()看一下执行结果,yield()方法不带参数。(4)wait()和notify()方法wait()方法的格式为wait(long time)或wait(long time,int nanos),time为等待的时间,单位为毫秒,nanos为附加等待时间,单位为纳秒。wait()方法使当前进程进入阻塞状态直到被唤醒或是等待的时间已到。wait()等价于wait(0),它使线程无限等待直到被唤醒。notify()方法用来唤醒一个正在等待的线程,一条notify();语句只能随机唤醒一个进程。使用notifyAll()方法可以唤醒所有在等待

177、的进程。需要指出的是这三个方法只能用在synchronized方法里。 (5)isAlive()方法isAlive()方法用来判断一个线程的run()方法是否还在执行,如果是则返回true,反之返回false。(6)join()方法如果一个线程在执行过程中需要等到另一个线程执行完才能继续执行就需要另一个进程调用join()方法,该方法也要捕获异常。join()方法也可以象wait()方法一样带参数表示需要另一个进程运行多长时间。【例【例7-10】join()方法应用,地铁建设工程程序方法应用,地铁建设工程程序public class JianZhu extends Thread /建筑队类建筑

178、队类public void run()System.out.println(地铁建设中地铁建设中);System.out.println(水泥用完了,通知运输队水泥用完了,通知运输队运输运输);Thread yunshu = new YunShu();/创建运输队创建运输队线程线程yunshu.start();System.out.println(建筑队等待水泥运到建筑队等待水泥运到);tryyunshu.join();/等待运输到达catch(Exceptione)/防止在等待中出现异常中断System.err.println(运输队途中遇阻);System.err.println(建设工程

179、停工);System.out.println(建设工程继续);public class YunShu extends Thread /运输队类public void run()System.out.println(运输队出发,水泥运回需要三小时);try for (int i=1; i5) /发射5次后退出System.exit(1);System.out.println(大炮第+i+次发送完毕,请装填炮弹);notify(); /唤醒装填手synchronized void load()while(shells) try wait();catch(InterruptedException e

180、) System.out.print(程序中断); shells=true;j+;if(j5)System.exit(1);System.out.println(炮弹装填完毕);notify(); /通知炮手 class Artillery extends Thread /炮手类Cannons cannon;Artillery(Cannons cannon)this.cannon=cannon;public void run()while(true)cannon.shot();class Filler extends Thread /装填手类Cannons cannon;Filler(Cann

181、ons cannon)this.cannon=cannon;public void run()while(true)cannon.load();public class Fight /战斗类 public static void main(String args) Cannons cannon=new Cannons();new Filler(cannon).start();/装填手线程new Artillery(cannon).start();/炮手线程 例7-12执行结果7.3 项目实战一 异常处理编程 1.实战内容 编写一个简单的程序,能够捕获数组越界和除数为零两种异常,并能被自定异常类

182、捕获。2.实战目的 通过实战掌握异常处理的原理与方法,掌握自定义异常类和抛出异常的方法。3.实战过程 本实战比较简单实现的方法也有很多,我们可以首先定义两个异常类,然后定义两个方法分别抛出这两个异常,被自定义异常类捕获。参考程序:class ChuLing extends Exception/自定义除零异常类public String toString()return :除数为零; class YueJie extends Exception/自定义数组越界异常类public String toString()return :数组越界; public class ShiXun1 public

183、static void main(String args)trychufa(5,1); /调用方法shuzu(6); /调用方法catch(ChuLing e)System.out.println(捕获了自定义异常+e); /捕获自定义异常catch(YueJie f)System.out.println(捕获了自定义异常+f);public static void chufa (int a,int b) throws ChuLing /声明除零异常int c=0;if(b=0)throw new ChuLing(); /抛出除零异常c=a/b;System.out.println(a+/+b

184、+的商为:+c);public static void shuzu(int a) throws YueJie /声明越界异常int b;b=new int5;if(a5)throw new YueJie(); /抛出越界异常for(int i=0;i50)System.exit(1);notify();System.out.println(n+消费产品库存量为: +count);System.out.println(共消费产品+i+个);count-;class Producer extends Threadprivate String name;private Storage s;publi

185、c Producer(String n, Storage s) name = n; this.s = s;public void run() while (true) s.shengchan(name);try sleep(int)Math.random()*1000);catch (InterruptedException e) System.out.println(程序意外中断); class Consumer extends Threadprivate String name;private Storage s;public Consumer(String n, Storage s) n

186、ame = n;this.s = s;public void run() while (true)s.xiaofei(name);try sleep(int)Math.random()*5000);catch (InterruptedException e) System.out.println(程序意外中断); public class ShiXu2public static void main(String argv)Storage s = new Storage();Producer p1 = new Producer(生产者, s);Consumer c1 = new Consumer

187、(消费者, s);p1.start();c1.start(); 项目小结 首先介绍了异常的基本概念、异常产生的原因及异常处理机制,重点讲解了在程序中异常处理的过程及异常处理的各关键字的用法,举例说明了自定义异常类的使用方法。随后介绍了Java语言中的多线程机制,讲解了实现多线程的两种方法,重点介绍了线程生命周期中的五种状态及各状态间的转换方法,也简要说明了线程的调度原理及线程控制的方法。项目8 输入输出流任务一掌握流及标准输入输出任务二掌握常用输入输出流的使用方法任务三掌握常用文件和目录操作项目实战一文件输入输出操作8. 8.1 1 掌握流及标准输入输出掌握流及标准输入输出 8.1.1 流及其

188、分类流及其分类流是输入流是输入/输出设备的一种抽象输出设备的一种抽象表示,这些设备是数据源头或表示,这些设备是数据源头或是数据终点。是数据终点。Java应用程序可以从数据源读取应用程序可以从数据源读取数据,向数据目的地写入数据。数据,向数据目的地写入数据。流最简单的分类:流最简单的分类:当向一个流写入数据的时候,这当向一个流写入数据的时候,这个流被称为输出流。个流被称为输出流。当从一个流读取数据的时候,这当从一个流读取数据的时候,这个流被称之为输入流。个流被称之为输入流。流可以按流动方向,处理位置,流可以按流动方向,处理位置,功能等分类,详细情况请看书功能等分类,详细情况请看书上的表上的表8-

189、1图8-1流是对输入输出设备一种抽象表示数据数据程序输入流输出流输入设备输出设备说明:(1 1) 首先,程序开发者可以使程序向流中写入数据或者从流中读出首先,程序开发者可以使程序向流中写入数据或者从流中读出数据,你可以把它流想象成一个流入或流出你的程序的有序的数数据,你可以把它流想象成一个流入或流出你的程序的有序的数据序列;据序列;(2 2) 其次,流必须连接到数据源或者数据目的地两端的任何一端,其次,流必须连接到数据源或者数据目的地两端的任何一端,你的应用程序可以通过流来向数据源读取数据,或还可以通过流你的应用程序可以通过流来向数据源读取数据,或还可以通过流向数据目的地写入数据,即流都有自己

190、的起点和终点,并且是顺向数据目的地写入数据,即流都有自己的起点和终点,并且是顺序的。流是一个通道,通向数据源或者数据目的地;序的。流是一个通道,通向数据源或者数据目的地;(3 3)要知道文件和流的差异。文件是一些具有永久存储及特定顺序要知道文件和流的差异。文件是一些具有永久存储及特定顺序的字节组成的一个有序的、具有名称的集合。因此,对于文件,的字节组成的一个有序的、具有名称的集合。因此,对于文件,人们常会想到目录路径、磁盘存储、文件名、文件和目录名等方人们常会想到目录路径、磁盘存储、文件名、文件和目录名等方面。相反,流提供一种向后备存储器写入字节和从后备存储器读面。相反,流提供一种向后备存储器

191、写入字节和从后备存储器读取字节的方式,后备存储器可以为多种存储媒介之一;取字节的方式,后备存储器可以为多种存储媒介之一; (4 4)数据源或数据目的地,凡是可以存储数据都可以作为前面两者)数据源或数据目的地,凡是可以存储数据都可以作为前面两者之一。之一。 在编写控制台应用程序时,程序要读取从键盘输入的数据。那么程序是怎样读取从键盘输入的数据呢?请看示例:【例8-1】从键盘按单个字节读取数据。package chapter08;public class ReadNormalInputStreamByByte /* * 程序8-1:按字节从键盘输入中读取数据 */public static voi

192、d main(String args) throws Exception / 从输入流中读取数据的下一个字节,返回 0 到 255 范围内的 int 字节值。int b=System.in.read(); / 如果因为已经到达流末尾而没有可用的字节,则返回值 -1 while(b!=-1)System.out.println(b);b=System.in.read();8.1.2 标准输入流标准输入流8.1.3 标准输出和标准错误1、 标准输出 在操作系统中定义的三个标准流中,另一个是标准输出流,它同样可以通过java的类System成员获得。它对应于命令行的输出,由封装在System类的静态

193、out成员中且为PrintStream类型。PrintStream类的主要写数据的方法:print(dataType data) 打印各种数据类型的值,dataType可以是Java的基本数据类型,也可以是字符数组、对象、字符串。println(dataType data) 打印各种数据类型的值,然后终止行。dataType可以是Java的基本数据类型,也可以是字符数组、对象、字符串。printf(参数.) 使用指定格式字符串和参数将格式化的字符串写入此输出流的便捷方法。 write(int b) 将指定的字节写入此流。 write(byte buf) 将 len 字节从指定的初始偏移量为 o

194、ff 的 byte 数组写入此流。 append(char ch) 将指定字符添加到此输出流。【例8-3】使用PrintStream流输出各种数据类型。packagechapter08;publicclassTestNormalOutputStreampublicstaticvoidmain(Stringargs)/输出各种数据类型System.out.println(HelloWorld!);/字符串System.out.println(true);/布尔类型System.out.println(23);/整型System.out.println(123.3f);/浮点数System.out

195、.println();/换行System.out.println(newchar7,8,9,4,5);/字符数组System.out.println(H);/字符类型System.out.println(0x234);/十六进制整数System.out.println(122.23d); /双精度小数System.out.println(你好!);/字符串System.out.append(A);/字符System.out.write(newbyte1,2,3,4);/字节数组System.out.flush();/刷新缓冲区的数据2、标准错误 标准错误输出流,在默认情况下它通常将错误信息映射

196、到命令行输出,由System类的err成员封装,且也是PrintStream类型。 Java的System类提供一些简单的静态方法调用,允许程序开发者对标准输入、输出、和错误流进行重定向:setIn(InputStream in) - 重新分配“标准”输入流。setOut(PrintStream out) - 重新分配“标准”输出流。setErr(PrintStream err) - 重新分配“标准”错误输出流。【例8-4】重定向方法的简单使用。主要代码如下:/获取标准输出流PrintStreamconsole=System.out;/创建一个Redirecting.java文件输入流,并对这

197、个基本文件输入流用/BufferedInputStream流进行装饰。BufferedInputStreamin=newBufferedInputStream(newFileInputStream(src/chapter08/Redirecting.java);/创建一个test.out文件输出流,并对这个基本文件输入流用/PrintStream流进行装饰。PrintStreamout=newPrintStream(newFileOutputStream(test.out);/重新定向标准输入流System.setIn(in);/重新定向标准输出流System.setOut(out);/重新定

198、向标准错误入流8.2 任务二 掌握常用输入输出流使用InputStream和OutStream类是所有字节输入流和输出流的基类。它们都是抽象类,不能被实例化,然而,这两个类都声明了一些方法,这些方法为它们所表示的流定义了操作的基本集合。它的子类对于读取二进制的数据很有用途。Reader流和Writer流是能够以字符流的方式读写字节流的对象,所以说字符流本质上就是一个读或写对象所面向的字节流。它们都是抽象类,不能被实例化,然而,这两个类都声明了一些方法,这些方法为它们所表示的流定义了读写字符的基本及相关操作集合。详细的输入输出流的层次结构及其上面四个类的方法,请看教材。8.2.3 FileInp

199、utStream类和FileOutStream类的使用FileInputStream类是文件输入流,是从文件系统中的某个文件中获得输入字节,主要针对读取的二进制类型的文件的内容情况下使用它在使用它时,必须先创建一个FileInputStream类的对象并且连接到数据源上,它提供了三个构造方法:upublic FileInputStream(File file)通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。upublic FileInputStream(String name)通过打开一个到实际文件的连接来创建一个

200、 FileInputStream,该文件通过文件系统中的路径名 name 指定。upublic FileInputStream(FileDescriptor fdObj)通过使用文件描述符 fdObj 创建一个 FileInputStream,该文件描述符表示到文件系统中某个实际文件的现有连接。在对流的相关操作结束后,一定要调用此方法关闭流,或者,应用程序或系统中有很多流打开的话,则耗资源。同样,FileOutStream类是文件输出流,是用于将数据写入 File 或 FileDescriptor 的输出流,主要针对写入的二进制类型的文件的内容情况下使用它。在使用它时,必须先创建一个FileO

201、utputStream类的对象并且连接到数据目的地上,它提供了五个构造方法。【例【例8-5】简单读取文件:读取】简单读取文件:读取Java应用程序的源代码并正确显示汉字。应用程序的源代码并正确显示汉字。importjava.io.*;publicclassFileInputStreamSimpeUsagepublicstaticvoidmain(Stringargs)bytebuffer=newbyte2056;tryFileInputStreamfileIn=newFileInputStream(src/chapter08/FileInputStreamSimpeUsage.java);in

202、tbytes=fileIn.read(buffer,0,2056);Stringstr=newString(buffer,0,bytes,gb2312);System.out.println(str);/输出字符串catch(Exceptione)/捕获异常/将异常信息转换为字符串Stringerr=e.toString();System.out.println(err);/输出异常信息【例8-6】编写一个复制文件的应用程序。代码见教材 说明:创建一个输入流fileIn连接到Sunset.jpg文件上和一个输出流fileOut连接到Sunset1.jpg文件上,若Sunset1.jpg不存在,

203、则会自动创建这个文件,如存在则会覆盖这个文件。声明一个1024长度的字节数组,每次从输入流fileIn中当前位置startPos读取1024个字节存放在buffer数组中,并把buffer数组的内容通过输入流写入到Sunset1.jpg文件中,把当前位置向后移动1024个字节,重复操作直到到达Sunset.jpg文件末尾。要注意是:输入输出流的特点,是每个数据都必须等待排在它前面的数据读入或送出之后才能读写,每次读写操作处理的是字节序列中剩余的未读写数据的第一个,而不能随意选择输入输出的位置,即读写数据是有序的。8.2.5 FileReader类和FileWriter类使用可知,FileRea

204、der和FileWriter是按字符读写的输入输出流。它的基类是InputStreamReader和OutputStreamReader。在前面知道,InputStreamReader和OutputStreamWriter的基类分别是Reader和Writer,而Reader类和Writer类以及它们的子类并不是流本身,而是提供了以字符流的形式读、写底层流的方法。因此,Reader对象或者Writer对象通常使用底层的InputStream对象和OutputStream对象来创建,InputStream对象和OutputStream对象封装有于外部设备的连接,这种外部设备就是最终的数据源或者数

205、据目的地。要创建一个FileReader对象有三个方法,即它有三个构造函数分别如下:uFileReader(Filefile) 在给定从中读取数据的 File 的情况下创建一个新 FileReader。uFileReader(StringfileName) 在给定从中读取数据的文件名的情况下创建一个新 FileReader。uFileReader(FileDescriptorfd) 在给定从中读取数据的 FileDescriptor 的情况下创建一个新 FileReader。使用方法请看书上的三个示例8.2.6 使用BufferedReader类实现各种数据类型的输入BufferedReade

206、r从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取,并且可把读出的内容转换成各种数据类型。这样,使用BufferedReader类可以实现各种数据类型的输入。例如BufferedReader在读取文本文件时,会先将字符数据读入缓冲区,而之后若使用read()方法时,会先从缓冲区中进行读取,如果缓冲区数据不足,才会再从文件中读取。使用BufferedWriter时,写出的数据并不会先输出至目的地,而是先储存至缓冲区中,如果缓冲区中的数据满了,才会一次对目的地进行写出,例如一个目标文件,使用缓冲区,同样可以减少对磁盘的I/O动作,可以提高程序的写数据的效率。这两个来的主要方法

207、在表8-8详细使用方法请看书上的三个示例 8.3 任务三 掌握常用目录和文件操作获取文件信息和更改文件属性u创建File对象,File类提供了四种构造方法,分别是:upublicFile(StringpathName)通过将给定路径名字符串转换为抽象路径名来创建一个新 File实例。upublicFile(Fileparent,Stringchild)根据 parent抽象路径名和 child路径名字符串创建一个新 File实例。upublicFile(Stringparent,Stringchild)根据 parent路径名字符串和 child路径名字符串创建一个新 File实例。upubl

208、icFile(Stringuri)通过将给定的 file:URI转换为一个抽象路径名来创建一个新的 File实例。读者要注意:File对象实际上并代表一个文件,File对象本身并不是物理文件或路径,而是封装了路径名或引用,该引用是指向硬盘上可能存在也可能不存在的物理文件或目录。所有创建File对象并不意味着文件或目录就一定存在。并且File类的实例是不可变的;也就是说,一旦创建,File对象表示的抽象路径名将永不改变。8.3.2 列目录文件清单列目录文件清单的File类的File对象的方法:Stringlist()返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。Stri

209、nglist(FilenameFilterfilter)返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。File listFiles()返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。File listFiles(FileFilterfilter)返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。File listFiles(FilenameFilterfilter)返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。8.3.3 获取根目录和创建子目录获取根目录和创

210、建子目录的File对象的方法:booleanmkdir() 创建此抽象路径名指定的目录。booleanmkdirs() 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。static FilelistRoots() 列出可用的文件系统根。 上面表格中两个对象方法、一个类方法,mkdir的功能是创建一个windows操作系统下的一个文件夹即目录,mkdirs的功能是创建多个文件夹,但是必须创建的文件夹是要创建的文件夹及其不存在的所祖先文件夹。8.3.4 文件的创建、更名和删除创建、更名和删除文件的File对象的方法:ubooleancreateNewFile() 当且仅当不存在具有此抽象

211、路径名指定名称的文件时,不可分地创建一个新的空文件。ustatic File createTempFile(String prefix, String suffix) 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。ustatic File createTempFile(String prefix, String suffix, File directory) 在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。ubooleanrenameTo(File dest) 重新命名此抽象路径名表示的文件。u booleandelete() 删除此抽象路径名表示的文

212、件或目录。u voiddeleteOnExit() 在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。请认真阅读一下【程序8-17】在当前目录下创建、更名、删除文件。并上机调试。8.3.5 基本数据类型数据的读写类DataInputStream是实现了DataInput接口,它允许应用程序以与机器无关方式从底层输入流中读取基本 Java数据类型。如int、float、long、double和boolean等等。此外,DataInputStream的readUTF()方法还能读取采用UTF-8字符编码的字符串。DataInputStream类的所有读方法采用了readXXX()模式。比如:

213、readByte()从输入流中读取1个字节,把它转换为byte类型的数据。 readerLong()从输入流中读取8个字节,把它转换为long类型的数据。readFloat()从输入流中读取4个字节,把它转换为float类型的数据readUTF()从输入流中读取1到3个字节,把它转换为采用UTF-8字符编码的字符串。程序工作原理:对于以上文件输入流,先用BufferedInputStream装饰,在读取数据时利用缓冲类装饰以便提高读取数据的效率,接着再用DataInputStream类装饰,从而具备读取格式化数据的功能。对于以上文件输出流也是同样的。以上程序输出的结果为:-21212中国 8.

214、3.6 使用增加了缓冲的流类使用增加了缓冲的流类主要有:字节数组输入流/输出流(ByteArrayInputStream、ByteArrayOutputStream)和字符数组输入流/输出流(CharArrayReader、CharArrayWriter),这些类都包含一个受保护的成员变量-内部缓冲区数组,并且连接上数据源或数据目的地是一个字节或字符数组。其中ByteArrayInputStream的成员变量protectedbytebuf的作用-由该流的创建者提供的 byte数组,字节缓冲区,而ByteArrayOutputStream类的成员变量protectedbytebuf的作用-存储

215、数据的字节缓冲区;CharArrayInputStream的成员变量protectedcharbuf的作用-字符缓冲区,CharArrayOutputStream类也有一成员变量protectedcharbuf的作用-存储数据的字符缓冲区。其中它的成员方法详细情况,请看它们的基类字节流及字符流。但它们还定义自己的成员方法。从下列示例程序中读者可以知道它们的用法。【例8-19】使用增加了缓冲的流类的用法。packagechapter08;importjava.io.*;publicclassByteOrCharArrayStreamUsagespublicstaticvoidmain(Strin

216、gargs)throwsIOExceptionbytebyteBuf=1,2,3,4,5,-12;charcharBuf=1,a,4,t,3;ByteArrayInputStreaminByteArray=newByteArrayInputStream(byteBuf);CharArrayReaderinCharArray=newCharArrayReader(charBuf,1,4);intdata=inByteArray.read();System.out.println(inByteArray.markSupported();System.out.println(inCharArray.

217、markSupported();System.out.println(inByteArray.available();while(data!=-1)System.out.println(data);inByteArray.skip(3);data=inByteArray.read();intch=inCharArray.read();while(ch!=-1)System.out.println(ch);ch=inCharArray.read();inByteArray.close();inCharArray.close();ByteArrayOutputStreamoutByteArray=

218、newByteArrayOutputStream(100);CharArrayWriteroutCharArray=newCharArrayWriter();outByteArray.write(byteBuf,2,2);outCharArray.write(charBuf,3,2);byteoutArray=outByteArray.toByteArray();for(byteb:outArray)System.out.println(b);System.out.println(outCharArray.toString();outByteArray.close();outCharArray

219、.close();8.3.7 读取文件指定行读取文件指定行要用到类LineNumberReader,它是跟踪行号的缓冲字符输入流,其基类是BufferedReader。它有两个构造方法:publicLineNumberReader(Readerin)使用默认输入缓冲区的大小创建新的行编号 reader,默认输入缓冲区的大小为8096个字节。pulbicLineNumberReader(Readerin,intsize)创建新的行编号 reader,将字符读入给定大小的缓冲区。例如:FileInputReaderin=newFileInputReader(“test.java”);LineNum

220、berReaderline=newLineNumberReader(in);此类的详细方法方法可参考8.3.2节它的基类Reader和JDK帮助文档,此外,它还定义了方法 setLineNumber(int)和 getLineNumber(),它们可分别用于设置和获取当前行号。默认情况下,行编号从 0开始。请看示例【程序8-20】读取文件指定行。程序工作原理:此类中定义了两个静态方法:getTotalLines(File file)方法获取文件内容如的总行数。其中,lines计数器用来存储总行数的。readingAppointedLN(File sourceFile,int lineNumbe

221、r)方法是读取指定行数,通过类LineNumberReader的对象方法readLine(),读取数据的单位为一行,最后关闭reader、in流。 8.4 项目实战一 文件输入输出操作 1.实战内容: 本实战要求读者编写一个有关文件输入输出的应用程序:实现操作系统中的复制功能,即复制一个文件或文件夹到另一个地方。运用前面所用的编程技能,正确的编写此应用程序。 2.实战目的: 通过实战,掌握文件输入输出流、File的使用;掌握File类的使用;掌握在文件处理中经常要使用的递归方法。 3.实战过程: 分析问题:拷贝一个文件的算法比较简单请参考程序8-6,当然,可以对它进行优化,比如使用缓冲流,提高

222、读写数据的效率等。但是在复制文件夹时,则需要利用Flie类在目标文件夹中创建相应的目录,并且使用递归方法。import java.io.*;public class CopyDirectory static String url1 = f:/photos;/ 源文件夹static String url2 = d:/tempPhotos;/ 目标文件夹public static void main(String args) throws IOException / 创建目标文件夹(new File(url2).mkdirs();/ 获取源文件夹当前下的文件或目录File file = (new

223、File(url1).listFiles();for (int i = 0; i file.length; i+) if (filei.isFile() / 复制文件copyFile(filei,new file(url2+filei.getName(); if (filei.isDirectory() / 复制目录String sourceDir=url1+File.separator+filei.getName();String targetDir=url2+File.separator+filei.getName();copyDirectiory(sourceDir, targetDir

224、);public static void copyFile(File sourceFile,File targetFile) throws IOException / 新建文件输入流并对它进行缓冲 FileInputStream input = new FileInputStream(sourceFile); BufferedInputStream inBuff=new BufferedInputStream(input); / 新建文件输出流并对它进行缓冲FileOutputStream output = new FileOutputStream(targetFile);BufferedOu

225、tputStream outBuff=new BufferedOutputStream(output);/ 缓冲数组byte b = new byte1024 * 5;int len;while (len =inBuff.read(b) != -1) outBuff.write(b, 0, len);outBuff.flush();/ 刷新此缓冲的输出流inBuff.close(); /关闭流outBuff.close();output.close();input.close(); / 复制文件夹public static void copyDirectiory(String sourceDi

226、r, String targetDir)throws IOException (new File(targetDir).mkdirs(); / 新建目标目录/ 获取源文件夹当前下的文件或目录File file = (new File(sourceDir).listFiles();for (int i = 0; i file.length; i+) if (filei.isFile() File sourceFile=filei; / 源文件/ 目标文件File targetFile=new File(new File(targetDir).getAbsolutePath()+File.sepa

227、rator+filei.getName();copyFile(sourceFile,targetFile);if (filei.isDirectory() / 准备复制的源文件夹String dir1=sourceDir + / + filei.getName();/ 准备复制的目标文件夹String dir2=targetDir + /+ filei.getName();copyDirectiory(dir1, dir2);项目小结 重点介绍了Java中的输入输出流和文件操作的基本概念及操作,并结合文件的输入和输出详细介绍了Java类库I/O包中的基本类使用。本章介绍了以下内容:流是对输入输

228、出设备的抽象表示;介绍了字节流和字符流的抽象基类及其子类;介绍了标准输入流、标准输出流及标准错误流,利用它们各自的setIn、setOut、setErr对象方法进行标准流的重定向;利用File类的对象可以封装文件或目录路径,并进行对文件对象的属性、有关文件或目录的创建、重命名、删除等操作;利用DataInputStream和DataOutputStream类实现Java基本数据类型的读写操作,要注意它们必须配套使用才能正确地读写Java基本数据类型。项目9 图形用户界面设计任务一任务一 了解与图形处理相关的包了解与图形处理相关的包任务二任务二 掌握掌握Java AppletJava Apple

229、t程序结构及运行程序结构及运行 任务三任务三 掌握使用掌握使用SwingSwing组件进行常用图形界面设计的方法组件进行常用图形界面设计的方法任务四任务四 掌握掌握图形的绘制方法掌握掌握图形的绘制方法项目实战一项目实战一 图形界面编程综合实训图形界面编程综合实训9.1 9.1 任务一任务一 了解与图形处理相关包了解与图形处理相关包9.1.1 java.awt包包图9-1JavaAWT包Menu-Popup MenuCheckboxMenuItemjava.lang.ObjectBorder LayoutCard LayoutCheckbox GroupColorComponentDimensi

230、onEventFontFlow LayoutFontMetricsGraphicsGridBag ConstraintsGridBag LayoutGrid LayoutMenuComponentImageInsetsPointPolygonRectangleToolkitButtonCanvasCheckboxChoiceContainerLabelListScrollbarTextComponentPanelWindowScrollPaneAppletDialogFrameMenuBarMenuItemTextAreaTextField【例例9-19-1】创建一个】创建一个AWTAWT窗体

231、。窗体。importjava.awt.*;publicclassexa9_1publicstaticvoidmain(Stringargs)Framef=newFrame(Thisisawindow!); f.setLocation(100,200); f.setSize(200,400); f.setBackground(Color.red); FlowLayoutfl=newFlowLayout(); f.setLayout(fl); Buttonb1=newButton(Ok!); f.add(b1); Buttonb2=newButton(Cancle!); f.add(b2); f.

232、setVisible(true); 说明:(1 1)、任何基于)、任何基于AWTAWT包的传统窗体程序都必须导入相应的包的传统窗体程序都必须导入相应的AWTAWT包以方便编程。包以方便编程。(2 2)、对于默认的新建窗体,其左上角总是对齐屏幕的左)、对于默认的新建窗体,其左上角总是对齐屏幕的左上角,大小只能显示出标题栏,所以,必须设置常见的上角,大小只能显示出标题栏,所以,必须设置常见的用于显示的属性。用于显示的属性。(3 3)、对于默认的新建窗体,并不直接显示,要想使窗体)、对于默认的新建窗体,并不直接显示,要想使窗体显示出来,必须设置显示出来,必须设置visiblevisible属性为真。

233、属性为真。(4 4)、构造函数中的参数可以用于设置窗体的标题,也可)、构造函数中的参数可以用于设置窗体的标题,也可以使用以使用setTitle()setTitle()方法后设置。方法后设置。(5 5)、添加组件的方法)、添加组件的方法 add(Component) add(Component),如:,如:add(button1)add(button1)。9.1.2 java.swing9.1.2 java.swing包包 图9-2Swing包结构图【例【例9-29-2】创建一个】创建一个SwingSwing窗体。窗体。importjavax.swing.*; importjava.awt.*;

234、 publicclassexa9_2publicstaticvoidmain(Stringargs)JFramef=newJFrame(Thisisawindow!);f.setLocation(100,200);f.setSize(200,400);FlowLayoutfl=newFlowLayout();f.getContentPane().setLayout(fl);JButtonjb=newJButton10;for(inti=0;ijb.length;i+)jbi=newJButton();jbi.setText(String.valueOf(i);f.getContentPane(

235、).add(jbi);f.setVisible(true);请注意和上述awt窗体的异同点:(1)、导入的包和AWT不一样。(2)、swing组件类名称和awt组件类名称相比,往往都是多个大写的“J”开头。(3)、不再直接向窗体添加组件,而是通过内容面板间接添加组件,所以,在添加组件的时候,需要取得当前窗体的内容面板。(4)、传统AWT组件的一些方法不再鼓励使用,相反,可以使用具有相似功能的新的方法,如按钮的setLabel()方法被setText()取代,当然,传统方法仍然可以使用。(5)、在Swing引入setDefaultCloseOperation()之前,AWT关闭窗口必须使用程序监

236、视窗口,获得相关操作并处理和做出响应。9.1.3 java.awt.event9.1.3 java.awt.event包包 设计图形用户界面的目的是为了方便用户与计算机进行交流,比如当用户单击命令按钮时,希望系统能完成一个动作,实现某种功能,这些交互的功能是由后台的事件处理接口来完成的,java.awt.event包就提供处理由 AWT 组件所激发的各类事件的接口和类。有关 AWT 事件模型的细节,请参见 java.awt.AWTEvent 类。事件由事件源所激发,向事件源注册的事件侦听器可接收有关特定事件类的通知,此包定义了事件和事件侦听器,以及事件侦听器适配器,它是让事件侦听器的编写过程更

237、为轻松的便捷类。 9.2 9.2 任务二任务二 掌握掌握java Applet java Applet 程序程序结构及运行结构及运行 9.3.1 Applet类及相关方法类及相关方法1. Applet程序的工作原理程序的工作原理网络浏览器HTML文件:.嵌入Applet.网络服务器浏览网页下载Applet字节码图9-4Applet工作原理 2. Applet类中的主要方法:类中的主要方法:(1)、publicvoidinit()(2)、publicvoidstart()(3)、publicvoidstop()(4)、publicvoiddestroy()(5)、publicvoidpaint(

238、Graphicsg)9.2.2 Applet程序建立及运行过程程序建立及运行过程1. 源程序的编辑与编译源程序的编辑与编译 2. 代码嵌入代码嵌入 3. Applet的运行的运行9.3 任务三任务三 掌握使用掌握使用Swing组件进行常用图形组件进行常用图形界面设计界面设计 Swing组件类型很多,按功能分类如下:(1)、顶层容器:有JFrame(框架), JWindow(窗体),JDialog(对话框)和JApplet(小应用程序)。它们属于swing中的四个重量级组件。顶层容器的重要性在于,除了Menubar所有的GUI组件都需要被包含在顶层容器的一个默认容器ContentPane中。(2

239、)、中间容器(又叫简单容器):有JPanel(面板),JSplitPane(拆分面板),JToolBar(工具栏),JScrollPane(滚动面板)和JTabbedPane(页签式面板)等。中间容器介于顶层容器与一般组件之间,是用来装别的组件用的,它是要被添加在顶层容器中的,能够使被它承载的组件能合适地、有组织地呈现出来。(3)、特殊容器:有JLayeredPanel、 JRootPane InternalFrame等,它们也是中间容器,但有着特殊的作用。(4)、基本组件:组件是一个可以以图形化的方式显示在屏幕上并能与用户进行交互的对象,例如JButton,JLabel,JList等,是最基

240、本图形用户界面的组成部分。9.3.1 窗口容器类JFrame使用 1. 1. 窗口类容器窗口类容器Swing提供了四个在屏幕上显示窗口的组件:JWindow、JFrame、JApplet和JDialog。这四个组件统称为顶层组件,它们相互之间的区别不明显,因为其余的swing组件都必须依附在此四组件之一上才能显示出来,又称之为窗体类容器。2. JFrame2. JFrame(窗体)类(窗体)类窗体类JFrame还叫框架类,是一种带有标题栏、菜单和边界的窗口,而且允许调整大小,是最重要的顶层容器之一,而且是应用程序构建框架时必须使用的顶层容器。JFrame类是AWT中Frame 类的子类,它还加

241、入了一些Swing所独有的特性。 (1)、构造方法:JFrame():构造一个新的不可见的窗体对象JFrame(String title):构造一个新的、不可见的、具有指定标题的窗体对象(2)、常用方法: public void setBound(int x,int y,int w,int h) :设置窗口左上角位置和窗口大小public void setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE):设定窗口响应用户的关闭操作public void setTitle(String title) :设置窗口标题public void setResizab

242、le(Boolen boolean) :设置窗口是否可调大小public void setLocation(int x,int y):设置窗口左上角位置public void pack():用紧凑方式自动设定窗口大小【例【例9-49-4】创建一个带组件的窗体实例。】创建一个带组件的窗体实例。import javax.swing.*; public class exa9_4 public static void main(String args) /创建一个带标题的窗体 JFrame jf1=new JFrame(这是窗体JFrame); JLabel jb1=new JLabel(欢迎你);f

243、1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE jf1.setLocation(300,200); /设置窗体的显示位置 jf1.setSize(320,240); /设置窗体的尺寸 jf1.getContentPane().add(jb1); jf1.setVisible(true); /设置窗体的可见性 9.3.2 容器的布局容器的布局Java常用的几种布局管理器有:FlowLayout流式布局BorderLayout边界布局GridLayout网格布局(GridLayout)CardLayout卡片布局GridBagLayout网格包布局1

244、FlowLayout流式布局 FlowLayout类的构造函数:FlowLayout():使用居中方式构造流式布局,并且组件间默认的水平和垂直间隔是5FlowLayout(int align):使用给定的对齐方式构造流式布局,并且组件间默认的水平和垂直间隔是5FlowLayout(int align, int hgap, int vgap):使用给定的对齐方式构造流式布局,并且指定组件间垂直和水平间隔FlowLayout类的常用函数:int getAlignment( ) :获得对齐方式void setAlignment(int align):设置对齐方式int getHgap() :获得组件

245、间的水平间隔void setHgap(int vgap) :设置组件间的水平间隔int getVgap() :获得组件间的垂直间隔void setVgap(int vgap):设置组件间的垂直间隔void removeLayoutComponent comp):从布局中移除指定的组件【例【例9-59-5】FlowLayoutFlowLayout流式布局管理器举例。流式布局管理器举例。importjavax.swing.*;importjava.awt.*;publicclassexa9_5publicstaticvoidmain(Stringargs)JFramef=newJFrame(Hel

246、lo!);f.setLocation(10,100);f.setSize(600,400);f.getContentPane().setLayout(newFlowLayout(); JButtonjb1=newJButton(Click1);JButtonjb2=newJButton(Click2);JButtonjb3=newJButton(Click3);f.getContentPane().add(jb1);f.getContentPane().add(jb2);f.getContentPane().add(jb3);f.setVisible(true);【程序分析】【程序分析】(1

247、1)、改变窗口的大小,那么组件的排列方式也会跟)、改变窗口的大小,那么组件的排列方式也会跟着变化。着变化。(2 2)、组件的顺序和组件的尺寸是确定的,不随窗口)、组件的顺序和组件的尺寸是确定的,不随窗口而改变。而改变。(3 3)、当然,流式布局管理器类也可以定义很多布局)、当然,流式布局管理器类也可以定义很多布局属性,从而进行必要的一些样式调整,如:将上例的属性,从而进行必要的一些样式调整,如:将上例的A A行改行改成成f.getContentPane().setLayout(newFlowLayout(1,10,1f.getContentPane().setLayout(newFlowLay

248、out(1,10,100)00)。2. BorderLayout 边界布局BorderLayout类的构造函数:public Borderlayout():构造一个边界布局管理器public Borderlayout(int hgap,int vgap):构造一个边界布局管理器,并且指定组件之间的垂直和水平间隔构造函数的参数 hgap代表水平间距;vgap代表垂直间距。BorderLayout类的常用函数:int getHgap() :获得组件间的水平间隔void setHgap(int vgap):设置组件间的水平间隔int getVgap() :获得组件间的垂直间隔void setVgap

249、(int vgap):设置组件间的垂直间隔void removeLayoutComponent comp):从布局中移除指定的组件【例【例9-69-6】BorderLayoutBorderLayout布局管理器应用举例。布局管理器应用举例。importjavax.swing.*;importjava.awt.*;publicclass exa9_6publicstaticvoidmain(Stringargs)JFramef=newJFrame(Hello!);f.setLocation(20,200);f.setSize(200,200);f.getContentPane().setLayo

250、ut(newBorderLayout(5,5);JButtonjb1=newJButton(1);JButtonjb2=newJButton(2);JButtonjb3=newJButton(3);JButtonjb4=newJButton(4);JButtonjb5=newJButton(5);f.getContentPane().add(jb1,BorderLayout.NORTH);f.getContentPane().add(jb2,BorderLayout.SOUTH);f.getContentPane().add(jb3,BorderLayout.EAST);f.getConten

251、tPane().add(jb4,BorderLayout.WEST);f.getContentPane().add(jb5,BorderLayout.CENTER);f.setVisible(true);【程序分析】 程序中定义了五个按钮,分别放置在BorderLayout布局的5个区域内,各个区域的间距为5,每个按钮大小自动调整到各个区域的大小,此窗口有以下特点:(1)改变窗口的大小,组件的排列方式保持不变(2)组件的大小会随窗口而改变(3)NORTH与SOUTH有确定的高度,WEST与EAST有确定的宽度,实际编程时,不一定所有的区域都有组件,如果四周的区域(West、East、North

252、、South区域)没有组件,则由Center区域去补充,但是如果Center区域没有组件,则保持空白,请试着修改程序观察效果。3. GridLayout网格布局GridLayout类的构造函数:public GridLayout ():构造一行一列的网格布局 public GridLayout (int row,int columns):构造具有指定行数和列数的网格布局public GridLayout (int row,int columns,int hgap,int vgap):构造具有指定行数和列数的网格布局,并指定组件间的水平垂直间隔GridLayout类的常用函数:init getR

253、ows() :获得此布局的行数void setRows(int rows) :设置此布局的行数init getColumns ():获得此布局的列数void setColumns (int cols):设置此布局的列数int getHgap() :获得组件间的水平间隔void setHgap(int vgap):设置组件间的水平间隔int getVgap() :获得组件间的垂直间隔void setVgap(int vgap):设置组件间的垂直间隔void removeLayoutComponent comp):从布局中移除指定的组件4. CardLayout4. CardLayout卡片布局卡

254、片布局 CardLayout类的构造函数:public CardLayout () :构造一个CardLayout布局 public CardLayout (int hgap,int vgap):构造个CardLayout布局,且指定各个组件间的水平和垂直间隔CardLayout类的常用函数:void first(Container c):显示第一个容器中的组件void last(Container c):显示最后一个容器中的组件void next (Container c):显示下一个容器中的组件void previous(Container c):显示上一个容器中的组件9.3.3 9.3.

255、3 字体与颜色的使用字体与颜色的使用 Font字体类的使用Font类的构造函数如下:public Font(String name,int stye,int size);其中:name是字体的名称,style是字体的风格, size是字体的大小。style的 取值为Font.BOLD粗体,Font.ITALIC斜体,Font.PLAIN无格式, Font.ITALIC+Font.BOLD粗斜体四者之一。2. Color颜色类的使用要为字体设置颜色可以使用Color类。每个Color对象代表一种颜色,使用方法有两种:(1)、直接使用Color类中已提供的颜色常量,如Color.black,Col

256、or.BLUE, Color.green, Color.yellow等.(2)、也可以通过调配三原色红、绿、蓝三色的比例来创建自己想要的颜色,如RGB。在RGB中,通过设定红黄蓝三种颜色的取值来获得自己想要的颜色,三种颜色的取值范围都是在0-255之间 9.3.4 9.3.4 按钮按钮按钮类按钮类JButtonJButton的构造方法:的构造方法:JButton()JButton():创建空文本的按钮:创建空文本的按钮JButton(String c) JButton(String c) :创建带指定文本的按钮:创建带指定文本的按钮JButton(Icon image) JButton(Ico

257、n image) :创建带指定图标的按钮:创建带指定图标的按钮JButton(String c ,Icon image)JButton(String c ,Icon image):创建带指定文本和图标的:创建带指定文本和图标的按钮按钮9.3.5 9.3.5 文本框、文本区和标签文本框、文本区和标签1. 文本框(JTextField)文本框JTextField的构造方法:JTextField() :创建空白文本的文本框JTextField(int columns) :创建指定宽度的空白文本域JTextField(String text) :创建指定文本的文本框JTextField(String

258、text, int columns):指定宽度并初始化文本 文本框其它常用方法:public void setText(String c):设置显示文本 public String getText():取得显示文本 public void setFont(Font f):字体设置 public void setForeground(Color c):前景色设置 public voidsetEditable(boolean b) :是否可编辑public StringgetSelectedText() :获得选择的文本public void setEchoChar(char c) :设置回显字符

259、另外常用一种用于输入密码的文本框类JPasswordField是文本框的一个子类,通常要用它的setEchoChar(char)方法设置回显字符。例如:JPasswordField userpwd = new JPasswordField();userpwd.setEchoChar(*);2. 2. 文本区(文本区(JTextAreaJTextArea)文本区是可以完成多行输入的可编辑文本框(JTextArea)。文本区JTextArea的构造方法:JTextArea():创建一个新的文本区组件JTextArea(int rows,int columns):创建指定行数r列数cJTextAre

260、a(String c) :创建指定初始化文本JTextArea(String c,int rows, int columns):创建指定初始化文本及文本的行数和列数常用设置方法:public void setLineWrap(boolean wrap):设置是否自动换行public void setRows(int rows) :设置行数public void setColumns(int columns):设置列数public void append(String c) :将指定文本追加到该组件结尾public void insert(String c ,int i):将指定文本插入文本区的

261、指定行public void setWrapStyleWord(Boolean b):设置换行方式3.3.标签标签 (JLabel) (JLabel)用来显示文字、图标,还可以文字与图标同时显示。标签JLabel的构造方法:JLabel( ) :创建一个空标签JLabel(String c) :创建指定文本的标签JLabel(String c ,Int i) :创建指定文本的标签,并且指定对齐方式(取值为 LEFT 、CENTER、 RIGHT)JLabel(String c ,Icon image,Int i):创建指定文本、图标和对齐方式的标签标签常用设置方法:设置标签显示文本:publi

262、c void setText(String c)取得标签显示文本:public String getText()字体设置:public void setFont(Font f)前景色设置: public void setForeground(Color c)9.3.6 9.3.6 事件处理模式与事件包事件处理模式与事件包 1.事件处理模式 这个模式涉及的主要概念:(1)、事件(Event)它描述在用户界面的用户交互行为所产生的一种效果,以类的形式出现,例如:鼠标操作对应的事件类是MouseEvent.(2)、事件源(Event Source)产生事件的场所,是一种组件对象。(3)、事件处理方法

263、(Event handler)接收、解析和处理事件类对象,实现和用户交互的方法。(4)、事件监听器(Event Listener)调用事件处理方法的对象。2.2.事件处理的实现原理事件处理的实现原理事件源(如按钮)事件监听器A事件监听器B事件监听器X事件处理者1事件处理者2事件处理者N使用授权处理模式进行事件处理主要有如图9-17所示几步::事件源(如按钮)事件监听器A事件监听器B事件监听器X事件处理者1事件处理者2事件处理者N图9-17事件处理原理3.3.事件包事件包ActionEventAdjustmentEventComponentEventItemEventTextEventFocus

264、EventInputEventContainerEventWindowEventKeyEventMouseEventjava.util.EventObjectjava.awt.AWTEvent图9-18AWTEvent类的相关事件9.3.7 9.3.7 复选框与单选按钮复选框与单选按钮 1. 1. 复选框复选框复选框JCheckBox的构造函数:JCheckBox(String c):创建带有文本标签的复选框JCheckBox(String c ,Boolean state):创建带文本和初始状态的复选框JCheckBox(Icon image):创建带图标的复选框JCheckBox(Icon

265、 image,Boolean state):创建带图标和初始状态的复选框JCheckBox(String c ,Icon image):创建带文本和图标的复选框JCheckBox(String c ,Icon image ,Boolean state) :创建带文本、图标和初始状态的复选框2. 2. 单选按钮单选按钮 JRadioButton类具有和JCheckBox相同参数和功能的构造函数。 JRadioButton类和JCheckBox共同的方法有: setSelected(Boolean):设置选中状态 isSelected():返回是否选中状态 为了对复选框进行分组,也可以使用使用Bu

266、ttonGroup进行分类. 注意初始化单选按钮时,一组中只能有一个状态设为true。当用户单击单选按钮时既能产生一个动作事件(ActionEvent),也能产生一个选项事件(ItemEvent),因此创建单选按钮时既可以注册动作监听器还可以注册选项监听器。9.3.8 9.3.8 列表框和组合框列表框和组合框1. 1. 列表框(列表框(JListJList)列表框JList的构造函数:public JList( ) :创建一个新的列表框public JList(ListModel dataModel):创建一个列表框,用它显示指定模型中的元素。 public JList (Object lis

267、tData):创建一个列表框,以显示指定数组listData的元素。 JList 不支持滚动,要启用滚动,可使用下列代码: JScrollPane myScrollPane=new JScrollPane();myScrollPane.getViewport().setView(dataList);2. 2. 组合框(组合框(JComboBoxJComboBox)JComboBox具有和JList相同参数和功能的构造函数。JComboBox的相关方法:addItem(int):向组合框内添加选项getItemAt(int):返回int指定的索引位置的列表项目的文本(从0开始)。getItemC

268、ount():返回列表中的项目的数量getSelectedIndex():返回列表中的当前选择项目的索引位置getSelectedItem():返回当前选择项目的文本getSelectedIndex(int):选择指定索引位置的项getSelectedIndex(Object):选择列表中指定的对象setMaximumRowCount(int):设置在组合框中的一次显示的行的数量9.3.9 9.3.9 对话框和文件选择对话框对话框和文件选择对话框 对话框分为模式对话框和无模式对话框。 模式对话框必须在用户处理完后才允许用户与主窗口继续进行交互。无模式对话框允许用户同时在对话框和程序剩余部分中输

269、入信息。 Java Swing中创建对话框使用JOptionPane和JDialog两个类,前者用来创建标准对话框,后者用于创建用户自定义的对话框。标准对话框都是模态对话框,后者JDialog创建的对话框既可是模态的也可是非模态的对话框。1. JOptionPane1. JOptionPane对话框类对话框类 在Swing中,JOptionPane提供了四种简单的对话框:(1)、消息对话框(Message Dialog)。 (2)、确认对话框(Confirm Dialog)。 (3)、选项对话框(Option Dialog)。 (4)、输入对话框(Input Dialog)。 这四个标准对话框

270、分别用于提出问题,警告用户,提供简要的重要消息的小窗口 2. JDialog2. JDialog对话框类对话框类JDialog类的构造方法:JDialog():建立一个无模态的对话框,没有title也不属于任何事件窗口组件。JDialog(Dialog owner):建立一个属于Dialog,non-modal形式,也没有title的对话框。JDialog(Dialog owner,Boolean modal):建立一个属于Dialog的对话框,可决定modal形式,但没有title。JDialog(Dialog owner,String title):建立一个属于Dialog组件的对话框,为

271、non-modal形式,对话框上有title。JDialog(Dialog owner,String title,Boolean modal):建立一个属于Dialog组件的对话框,可决定modal形式,且对话框上有title。JDialog(Frame owner):建立一个属于Frame组件的对话框,为non-modal形式,也没有title。JDialog(Frame owner,Boolean modal):建立一个属于Frame组件的对话框,可决定modal形式,但没有title。JDialog(Frame owner,String title):建立一个属于Frame组件的对话框,

272、为non-modal形式,对话框上有title。JDialog(Frame owner,String title,Boolean modal):建立一个属于Frame组件的对话框,可决定modal形式,且对话框上有title。3. JFileChooser3. JFileChooser文件选择对话框类文件选择对话框类: : JFileChooser类的构造函数:JFileChooser():构造一个指向用户默认目录的JFileChooser,此默认目录通常取决于操作系统,如win是我的文档,unix上则是用户主目录。JFileChooser(String currentDirectoryPat

273、h):构造一个指向给定路径的JFileChooser。JFileChooser(File currentDirectory):给定的File作为路径来构造一个JFileChooser。常用方法如下:public int showDialog(Component parent, String text):显示文件选择对话框,用户可自定义文本(默认“打开”)。public int showSaveDialog(Component parent) :显示文件保存对话框。public File getSelectedFile():返回所选择的文件。9.3.10 9.3.10 菜单菜单 在GUI界面中,

274、菜单一般位于窗口上方标题栏下面的位置,它是一个图形用户界面不可缺少的组成部分。一个菜单由三部分组成:JMenuBar菜单栏,在其中可以加入菜单(JMenu)JMenu菜单,其中可加入菜单项(JMenuItem)和菜单(JMenu)JMenuItem菜单项,直接指向一个具体的操作菜单、菜单项和菜单栏的构造方法:菜单栏: JMenuBar()菜单: JMenu(String s)菜单项: JMenuItem(String s)1. 1. 菜单条(菜单条(JMenuBarJMenuBar)一个菜单条组件是一个水平菜单。菜单条只能加入到一个框架中,一个菜单条由多个 菜单(JMenu )组成,每个 JM

275、enu 在 JMenubar 中都表示为字符串,如: JFrame f = new JFrame(JMenuBar);JMenuBar mb = new JMenuBar(); f.setJMenuBar(mb); 在一个时刻,一个框架中可以显示一个菜单条,菜单条不支持监听者。2. 2. 菜单(菜单(JMenuJMenu) 提供了一个基本的下拉式菜单,它可以加入到一个菜单条或者另一个菜单中。它在菜单栏下以文本字符串形式显示,而在用户单击它时,则以弹出式菜单显示.3. 3. 菜单项菜单项(JMenuItem)(JMenuItem)菜单项组件通常被加入到菜单中,以构成一个完整的菜单,以文本字符串形

276、式显示。JMenuItem 的外观可以修改,如字体、颜色、背景、边框等。除字符串外,在 JMenuItem 中还可以添加图标。通常我们将一个ActionListener加入到一个菜单项对象中,以提供菜单的行为。4. 4. 复选菜单项复选菜单项(JCheckboxMenuItem) (JCheckboxMenuItem) 一个可复选的菜单项,可以在菜单上有选项(“开”或“关”) 。应当用ItemListener接口来监视复选菜单。当复选框状态发生改变时,就会调用itemStateChanged()方法。JMenu m1 = new JMenu(File);JMenuItem mi1 = new

277、JMenuItem(Save); JCheckboxMenuItem mi2 = new JCheckboxMenuItem(checkbox1); mi1.addItemListener(this); mi2.addItemListener(this); m1.add(mi1); m1.add(mi2); 5. 5. 单选按钮菜单项单选按钮菜单项(JRadioButtonMenuItem)(JRadioButtonMenuItem) 它是属于一组菜单项中的一个菜单项,该组中只能选择一个项。被选择的项显示其选择状态。选择此项的同时,其他任何以前被选择的项都切换到未选择状态。要控制一组单选按钮菜

278、单项的选择状态,请使用JButtonGroup 对象。JButtonGroup group = new JButtonGroup();JRadioButtonMenuItem mi3 = new JRadioButtonMenuItem(Forward);group.add(mi3);m1.add(mi3);6. 6. 弹出式菜单弹出式菜单(JPopupMenu)(JPopupMenu)弹出式菜单提供了一种独立的菜单,它可以在任何组件上显示。可以将菜单项和菜单加入到弹出式菜单中去。7. 7. 菜单项的使用状态菜单项的使用状态 菜单项能够被选取取决于菜单项的启用和禁用状态:mi3.setEnab

279、led(false); /初始设置“Save”菜单项为禁用状态8. 8. 快捷键和加速器快捷键和加速器 快捷键显示为带有下划线的字母,加速器则显示为菜单项旁边的组合键。m1.setMnemonic(F); /设置菜单的快捷键JMenuItem exitItem = new JMenuItem(Exit, T); /设置“Exit”菜单项的快捷键为“T”。exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_MASK); /设置“Exit”菜单项的加速器为“CtrlT”。9.4 任务四 掌握图形

280、的绘制 9.4.1 坐标系统 (0,0)X轴图9-27Java窗口坐标系9.4.2 9.4.2 显示字符串显示字符串字符串绘制方法:public void drawString(String str,int x,int y) :在(x,y)点显示字符串str。 public void drawChars(char c,int s,int n,int x,int y):在(x,y)点显示字符数组c从位置s开始的n个内容。 public void drawBytes(byte b,int s,int n,int x,int y) :在(x,y)点显示字节数组b从位置s开始的n个内容。9.4.3 9

281、.4.3 画直线与矩形画直线与矩形Graphics类中用于绘制直线与矩形的方法如下:public abstract void drawLine(int x1, int y1, int x2, int y2):在点(x1,y1)和(x2,y2)之间用当前颜色绘制线段。public void drawRect(int x, int y, int width, int height):以点(x,y)为左上角坐标,width和height为宽度和高度,用当前颜色画矩形。public abstact void fillRect(int x, int y, int width, int height):以

282、点(x,y)为左上角坐标,width和height为宽度和高度,用当前颜色画一个实心的矩形。public abstact void clearRect(int x, int y, int width, int height):以点(x,y)为左上角坐标,width和height为宽度和高度,用当前背景颜色画一个实心的矩形。此方法用于清除某个矩形显示区域。public abstact void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight):以点(x,y)为左上角坐标,width和he

283、ight为宽度和高度,用当前颜色画圆角矩形。public abstact void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight):以点(x,y)为左上角坐标,width和height为宽度和高度,用当前颜色画一个实心的圆角矩形。 public void draw3Drect(int x, int y, int width, int height, boolean b):用指定的width和height,以当前颜色画一个三维矩形。矩形的左上角坐标为(x,y)。当b为true时,矩形为

284、凸的;b为false时,矩形为凹的。public void fill3Drect(int x, int y, int width, int height, boolean b):用指定的width和height,以当前颜色画一个填充的三维矩形。矩形的左上角坐标为(x,y)。当b为true时,矩形为凸的;b为false时,矩形为凹的。9.4.4 9.4.4 画圆、椭圆与圆弧画圆、椭圆与圆弧Graphics类中用于绘制圆、椭圆与圆弧的方法如下:public abstract void drawOval(int x, int y, int width, int height):用指定的width和h

285、eight,以当前颜色画椭圆。外切矩形的左上角坐标为(x,y)。当width=height时画出来的就是圆.public abstract void fillOval(int x, int y, int width, int height):用指定的width和height,以当前颜色画实心椭圆。外切矩形的左上角坐标为(x,y)。 public abstract void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle):参考外切矩形的左上角坐标(x,y),用指定的width和height,以当

286、前颜色绘制一段弧。弧段从起始角startAngle开始一直到张角arcAngle。public abstract void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle):参考外切矩形的左上角坐标(x,y),用指定的width和height,以当前颜色绘制一段实心的弧。弧段从起始角startAngle开始一直到张角arcAngle。9.4.5 9.4.5 画多边形与带颜色图形画多边形与带颜色图形Graphics类中用于绘制多边形与带颜色图形的方法如下:public abstract void

287、drawPolygon(int xPoints, int yPoints, int points):以当前颜色画一个具有points个顶点的多边形。xPoint和yPoint数组分别指定了每个顶点的x和y坐标。public void drawPolygon(Polygon p):以当前颜色画指定的多边形。public abstract void fillPolygon(int xPoints, int, yPoints, int points):以当前颜色画一个具有points个顶点的填充多边形。xPoint和yPoint数组分别指定了每个顶点的x和y坐标。 9.5 项目实战一 图形界面编程综

288、合实训1.实战内容本实训要求读者运用前面所用的编程技能,编写一个比较复杂的GUI综合界面设计程序。该例应用了各种常用组件,并实现了它们的合理摆放,而且当用户单击“文字”按钮的时候,还能实现简单的单击效果,显示一个修改界面。运行效果如图9-23所示。2.实战目的通过实战掌握Swing包中各种常用组件和常用的布局管理器的使用方法,掌握事件处理的过程,熟练的使用JAVA语言制作图形界面。3.实战过程参考代码如下:import java.util.*;import java.awt.*;import javax.swing.*;import java.awt.event.*;import javax.

289、swing.event.*;public class guiagg implements ActionListener,ItemListener,ListSelectionListener JRadioButton button_yellow, button_red,button_green; JLabel jl; JButton jb_change, jb_exit; JCheckBox jchk_bold, jchk_italic; JComboBox jcbo; JList jlst;public guiagg() JFrame jf=new JFrame(); jf.setSize(8

290、00,400); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jl=new JLabel(,JLabel.CENTER); jl.setFont(new Font(隶书,Font.BOLD,40); jl.setText(我们都来学JAVA); jb_change=new JButton(文字); jb_exit=new JButton(退出); jb_change.addActionListener(this); jb_exit.addActionListener(this); button_yellow=new JRadioButt

291、on(黄);button_red=new JRadioButton(红); button_green=new JRadioButton(绿);ButtonGroup bg=new ButtonGroup(); bg.add(button_yellow);bg.add(button_red);bg.add(button_green); button_yellow.addActionListener(this);button_red.addActionListener(this); button_green.addActionListener(this); jchk_bold=new JCheck

292、Box(加粗);jchk_italic=new JCheckBox(倾斜); jchk_bold.addActionListener(this);jchk_italic.addActionListener(this); jcbo=new JComboBox(); jcbo.addItem(12);jcbo.addItem(28);jcbo.addItem(36); jcbo.addItem(48);jcbo.addItemListener(this); jlst=new JList();Vector vv=new Vector(); vv.add(楷体);vv.add(隶书);vv.add(黑

293、体);jlst.setListData(vv); jlst.addListSelectionListener(this); JPanel jp=new JPanel(new BorderLayout(); JPanel jpc=new JPanel(); JPanel jp1=new JPanel(new GridLayout(4,1); JPanel jpl1=new JPanel();JPanel jpl2=new JPanel(); JPanel jpl3=new JPanel();JPanel jp2=new JPanel(); JPanel jp3=new JPanel (); JP

294、anel jps=new JPanel(new FlowLayout(FlowLayout.LEFT,40,10); FlowLayout fl=new FlowLayout(FlowLayout.LEFT); jpl1.setLayout(fl);jpl2.setLayout(fl); jpl3.setLayout(fl);jp2.setLayout(fl); jpl1.add(new JLabel(请选择前景色:); jpl1.add(button_yellow);jpl1.add(button_red);jpl1.add(button_green); jpl2.add(new JLabe

295、l(请选择字形:); jpl2.add(jchk_bold); jpl2.add(jchk_italic); jpl3.add(new JLabel(请选择字号:); jpl3.add(jcbo); jpc.add(jl); jp1.add(jpl1); jp1.add(jpl2); jp1.add(jpl3); jp2.add(new JLabel(请选择字体:); jp2.add(jlst); jp3.add(jb_change); jp3.add(jb_exit); jps.add(jp1); jps.add(jp2); jps.add(jp3); jp.add(jpc,BorderLa

296、yout.CENTER); jp.add(jps,BorderLayout.SOUTH); jf.getContentPane().add(jp); jf.setVisible(true);public void itemStateChanged(ItemEvent e)/单击列表框 fontset();public void valueChanged(ListSelectionEvent e)/单击下拉列表框 fontset();public void actionPerformed(ActionEvent e )/单击单选按钮,复选按钮,命令按钮等 if(e.getSource()=but

297、ton_yellow) jl.setForeground(Color.yellow); if(e.getSource()=button_red) jl.setForeground(Color.red); if(e.getSource()=button_green) jl.setForeground(Color.green); if(e.getSource()=jchk_bold) fontset(); if(e.getSource()=jchk_italic) fontset(); if(e.getSource()=jb_change) String str = JOptionPane.sho

298、wInputDialog(请输入内容:); jl.setText(str);if(e.getSource()=jb_exit) int jopvalue=JOptionPane.showConfirmDialog(null,您确定要退出吗?,提示!,JOptionPane.YES_NO_OPTION); if(jopvalue=JOptionPane.YES_OPTION) System.exit(0); void fontset() /设置字体 int fstyle=Font.PLAIN; if(jchk_bold.isSelected() fstyle=Font.PLAIN|Font.BO

299、LD;if(jchk_italic.isSelected() fstyle=fstyle|Font.ITALIC; Object folst=jlst.getSelectedValue(); String fname=楷体; if(!(folst=null) fname=folst.toString(); Object focbo=jcbo.getSelectedItem(); int fsize=12; if(!(focbo=null) fsize=Integer.parseInt(focbo.toString(); jl.setFont(new Font (fname,fstyle,fsi

300、ze); public static void main (String args) new guiagg(); 项目小结 通过本项目的学习,我们了解了Java常用的Swing组件、事件处理模型和基本图形绘制的用法。Swing提供了一整套的GUI组件,包括文本组件、标签、选择类组件、边界、菜单、对话框等。用于选择性输入的常用组件有JCheckBox、JRadioButton、JList、JComboBox等。Java中的布局种类包括:Flowlayout(从上到下,从左到右依次摆放,每行均居中,它是Panel、Applet的默认布局);BorderLayout(将容器内的空间划分为东、南、西、

301、北、中五个部分,并指明组件所在的部分,是Window、Dialog、Frame的默认布局方式);CardLayout(卡片叠式布局)将组件像卡片一样放置在容器中,在某一时刻只有一个组件可见,GridLayout(行列网格状布局);形似一个无框线的表格,每个单元格中放一个组件;用setLayout(null)命令可以不使用布局(NULL布局),此时可以对组件进行绝对定位。菜单是 GUI 中非常有用的一部分,包括菜单栏JMenuBar类、菜单JMenu类、菜单项JMenuItem类。项目10 键盘与鼠标事件的响应 任务一 掌握事件处理机制任务二 掌握对键盘事件响应的方法任务三 掌握对鼠标事件的响应

302、方法项目实战一 键盘事件响应项目实战二 鼠标事件响应10.1 任务一 掌握事件处理机制 10.1.1 相关概念1 1事件:是一个对象,它描述发生了什么事情。事件对象事件:是一个对象,它描述发生了什么事情。事件对象由在由在JavaJava中预先定义好的类产生,中预先定义好的类产生,JavaJava定义了所有事件的定义了所有事件的事件类,如键盘操作对应的事件类是事件类,如键盘操作对应的事件类是KeyEventKeyEvent。java.awt.AWTEventjava.awt.AWTEvent类是所有事件类的父类。类是所有事件类的父类。2 2事件源:能够产生事件的对象都可以称之为事件源,如事件源:

303、能够产生事件的对象都可以称之为事件源,如键盘、鼠标、按钮等。键盘、鼠标、按钮等。3 3事件处理方法:能够接收、解析处理事件类对象,实现事件处理方法:能够接收、解析处理事件类对象,实现和用户交互的方法。它以事件对象为参数。和用户交互的方法。它以事件对象为参数。4 4监视器:对事件源进行监视,使发生事件时做出处理的监视器:对事件源进行监视,使发生事件时做出处理的一种特殊的对象。事件源通过调用相应的方法将某个对象一种特殊的对象。事件源通过调用相应的方法将某个对象作为自己的监视器。作为自己的监视器。10.1.2 事件处理机制JavaJava采用采用“授权事件模型授权事件模型”(Event Delega

304、tion ModelEvent Delegation Model)的)的事件处理模式。其原理为:事先定义多种事件类型(即事件处理模式。其原理为:事先定义多种事件类型(即用户在用户在GUIGUI组件上进行的操作,如单击事件),当用户组件上进行的操作,如单击事件),当用户对某个对某个GUIGUI组件进行操作时,可能触发相应的事件,这组件进行操作时,可能触发相应的事件,这个组件就是事件源。如果此组件注册了事件监听器(可个组件就是事件源。如果此组件注册了事件监听器(可以通过以通过addXXXXListeneraddXXXXListener方法注册),事件被传送给已方法注册),事件被传送给已注册的监听器

305、,事件监听器负责处理事件的过程。一个注册的监听器,事件监听器负责处理事件的过程。一个组件可以注册一个或多个监听器。组件可以注册一个或多个监听器。监视器负责处理事件源发生的事件。监视器是个对象,为了处理事件源发生的事件,监视器会自动调用一个方法来处理事件。为了让监视器能对事件源发生的事件进行处理,创建该监视器的类必须声明实现相应的接口,即必须在类体中给出该接口中所有方法的方法体,这样在事件源发生事件时,监视器就自动调用执行被类实现的某个接口方法 若要保证一个组件产生的某种类型事件XXXEvent有效,需要注册一个“事件监听器”监听它。用如下语句设置事件监听器:事件源.addXXXListener

306、(XXXListener代表某种事件监听器)。组件作为事件源,不同类型的组件会产生特定类型的事件。 一旦产生事件后,事件会被传送给已注册的一个或多个监听器。事件监听器是实现了与该事件相对应的XXXListener接口的类。事件监听器监听到事件后,会根据事件的类型调用相应的事件处理方法。 事 件 源产生事件事件1事件2监视器1监视器2捕获事件事件处理事件处理图10-1 事件处理模型1 1java.awt.eventjava.awt.event包包(1)(1)文本框回车、按钮单击、计时器、菜单项文本框回车、按钮单击、计时器、菜单项引发动作事件:引发动作事件:java.awt.event.Actio

307、nEventjava.awt.event.ActionEvent处理事件的接口:处理事件的接口:java.awt.event.ActionListenerjava.awt.event.ActionListener接口中的方法:接口中的方法:public void actionPerformed(ActionEvent public void actionPerformed(ActionEvent event)event)(2)(2)单选按钮、多选按钮、下拉列表单选按钮、多选按钮、下拉列表引发选项事件:引发选项事件:java.awt.event.ItemEventjava.awt.event.I

308、temEvent处理事件的接口:处理事件的接口:java.awt.event.ItemListenerjava.awt.event.ItemListener接口中的方法:接口中的方法:public void itemStateChanged(ItemEvent public void itemStateChanged(ItemEvent event)event)(3)键盘引发动作事件:java.awt.event.KeyEvent处理事件的接口:java.awt.event.KeyListener(4)鼠标引发鼠标事件:java.awt.event.MouseEvent处理事件的接口:java

309、.awt.event.MouseListener与java.awt.event.MouseMotionListener接口。2java.swing.event包(1)列表(JList)引发列表选择事件:java.swing.event.ListSelectionEvent处理事件接口:java.swing.event.ListSelectionListener接口中的方法:publicvoidvalueChanged(ListSelectionEventevent)(2)树(JTree)引发树选择事件:java.swing.event.TreeSelectionEvent处理事件接口:java

310、.swing.event.TreeSelectionListener接口中的方法:publicvoidvalueChanged(TreeSelectionEventevent) (3)滑动杆(JSlider)引发改变事件:java.swing.event.ChangeEvent处理事件接口:java.swing.event.ChangeListener接口中的方法:publicvoidstateChanged(ChangeEventevent)10.2任务二掌握对键盘事件响应方法10.2.1键盘事件当键盘按下、释放、点击时都会触发键盘事件当键盘按下、释放、点击时都会触发键盘事件(java.aw

311、t.event.KeyEvent),常用的,常用的KeyEvent方法是方法是public int getKeyCode(),它用于获取所按下键的编码,它用于获取所按下键的编码值。值。键盘事件类提供了很多静态常量表示键的编码值,如:键盘事件类提供了很多静态常量表示键的编码值,如:VK_A 键键A的编码值的编码值VK_DOWN 下箭头键的编码值下箭头键的编码值VK_UP 上箭头键的编码值上箭头键的编码值VK_1 键键1的编码值的编码值VK_ENTER 表示回车编码值表示回车编码值VK_SPACE 表示空格键编码值表示空格键编码值更多的键码值可以查阅JavaAPI文档来获得。编写键盘事件响应程序时

312、,使用语句if(e.getKeyCode()=KeyEvent.VK_B)可以判断是否按下了字母键B,然后做相应处理,语句中的e是事件处理时接收的键盘事件对象参数名。10.2.2 键盘监听接口KeyListener对键盘事件可以通过java.awt.event.KeyListener接口中提供的方法来处理。这个接口有三个方法:1keyPressed(KeyEvent e)响应按下键盘事件;2keyTyped(KeyEvent e)响应按下又松开键盘事件;3keyReleased(KeyEvent e)响应松开键盘事件;它们都是public void方法,事件源要使用addKeyListener

313、方法添加监视器来获得事件。【例10-1】对键盘事件进行响应。importimport java.awt.event.*;importimport javax.swing.*;importimport java.awt.*;publicpublic classclass hh extendsextends JFrame implementsimplements KeyListenerJButton JButton1;hh() JPanel jpanel1=newnew JPanel();JButton1=newnew JButton(请按M键!);JButton1.addKeyListener(

314、thisthis);thisthis.setSize(200,300);thisthis.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jpanel1.add(JButton1);thisthis.add(jpanel1);thisthis.setVisible(truetrue);public void keyPressed(KeyEvent e)public void keyPressed(KeyEvent e)if(e.getKeyCode()=KeyEvent.if(e.getKeyCode()=KeyEvent.VK_MVK_M) )

315、JButton1.setBounds(60,60,90,90); JButton1.setBounds(60,60,90,90);JButton1.setBackground(Color.JButton1.setBackground(Color.redred);); public void keyReleased(KeyEvent e)public void keyReleased(KeyEvent e)public void keyTyped(KeyEvent e)public void keyTyped(KeyEvent e)public static void main(String a

316、rgs)public static void main(String args)new hh();new hh(); 10.2.3 键盘适配器类KeyAdapter使用KeyListener接口时,即使有些方法不使用也必须在程序中写出接口的所有方法,因此比较麻烦,而java.awt.event.keyAdapter类本身就使用了KeyListener接口,并对接口的三个方法增加了空方法体,因此使用keyAdapter类时不必像使用接口那样实现所有方法,只需覆盖要响应的键盘事件方法即可。下面的程序是通过使用键盘适配器类来实现响应键盘事件,当分别按“R”、“G”、“B”时将圆的颜色设置为红色、绿色

317、和蓝色。【例10-2】import java.awt.event.*;import javax.swing.*;import java.awt.*;public class hh extends JFrameColor c;hh()this.setSize(200,300);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);addKeyListener(new MyType();class MyType extends KeyAdapter public void keyTyped(KeyEven

318、t e) if(e.getKeyChar()=r|e.getKeyChar()=R) c=Color.red; else if(e.getKeyChar()=g|e.getKeyChar()=G) c=Color.green;else if(e.getKeyChar()=b|e.getKeyChar()=B) c=Color.blue; else c=Color.black; repaint(); public void paint(Graphics g) g.setColor(c);g.fillOval(60,60,100,100); public static void main(Stri

319、ng args) new hh(); 10.3 任务三 掌握对鼠标事件的响应方法10.3.1 鼠标事件鼠标事件源各种动作可以触发鼠标事件,如按下鼠标、点击鼠标、释放鼠标、鼠标进入和鼠标退出。鼠标事件类型是java.awt.event.MouseEvent,当发生鼠标事件时MouseEvent类自动创建一个鼠标事件对象。1MouseEvent类有几个常用的方法:(1)getX()用于获取鼠标x坐标(2)getY()用于获取鼠标y坐标;(3)getButton()用于获取鼠标的左中右键值;根据键值来知道按的是哪一个键,MouseEvent.BUTTON1、MouseEvent.BUTTON2和Mo

320、useEvent.BUTTON3分别是左中右三个键值。例如在程序中通过if(e.getButton()=MouseEvent.BUTTON1)可以判断按的是否是左键。(4)getClickCount()获取点击次数;2添加鼠标监视器的方法:public void addMouseListener()。3移去鼠标监视器的方法:public void removeMouseListener().10.3.2 使用MouseListener接口处理鼠标事件通过使用java.awt.event.MouseListener接口可以对鼠标事件进行处理,它有以五个方法:(1)mousePressed(Mou

321、seEvent)方法,按下鼠标时,接口监视器发现这个事件后自动调用这个方法。(2)mouseReleased(MouseEvent)方法,松开鼠标时,接口监视器发现这个事件后自动调用这个方法。(3)mouseEntered(MouseEvent)方法,鼠标指针进入容器时,接口监视器发现这个事件后自动调用这个方法。(4)mouseExited(MouseEvent)方法,鼠标指针离开容器时,接口监视器发现这个事件后自动调用这个方法。(5)mouseClicked(MouseEvent)方法,点击鼠标时,接口监视器发现这个事件后自动调用这个方法。这五个方法不管鼠标按键是左中右都会执行,如果要根据不

322、同键进行不同处理就要先用getButton()方法来判断。下面通过例10-3来说明如何用MouseListener接口来响应鼠标事件 【例10-3】import java.awt.*;import java.applet.*;import java.awt.event.*;public class m1 extends Applet implements MouseListenerTextField text1; int x;public void init()x=10;text1=new TextField(40);add(text1);text1.setFont(new Font(隶书,F

323、ont.BOLD,20);addMouseListener(this); public void mousePressed(MouseEvent e)text1.setText(鼠标被按下,重新画圆!);repaint();public void mouseReleased(MouseEvent e)text1.setText (鼠标被松开,指针坐标是:+e.getX()+,+e.getY();public void mouseEntered(MouseEvent e)text1.setText (鼠标进入文本框,指针坐标是:+e.getX()+,+e.getY();public void m

324、ouseExited(MouseEvent e)text1.setText (鼠标离开文本框了!);public void mouseClicked(MouseEvent e)if(e.getClickCount()=2)text1.setText (双击鼠标,指针坐标是:+e.getX()+,+e.getY();public void paint(Graphics g) x=x+5;g.setColor(Color.red);g.drawOval( 60, 60,x,x );g.setColor(Color.blue);g.fillOval(60,60,x,x);10.3.3 使用Mouse

325、MotionListener接口处理鼠标事件MouseListener接口中没有鼠标移动(不按下鼠标)和拖动(按下鼠标)的事件处理,对这两种事件响应就要用java.awt.event.MouseMotionListener接口来处理。它有两个方法:1)mouseDragged(MouseEvent)处理鼠标拖动事件2)mouseMoved(MouseEvent)处理鼠标移动事件事件源添加监视器方法:public void addMouseMotionListener()通过下面的画画程序我们了解一下使用MouseMotionListener接口处理鼠标事件的方法。【例10-4】import j

326、ava.awt.*;import java.applet.*;import java.awt.event.*;public class m2 extends Applet implements MouseMotionListenerint x=0,y =0;public void init() setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);setBackground(Color.green);addMouseMotionListener(this); public void paint(Graphics g) if(x!=0&

327、y!=0)g.setColor(Color.red);g.drawLine(x,y ,x,y);/起点与终点相同则画一个点 public void mouseDragged(MouseEvent e)x=(int)e.getX();y=(int)e.getY();repaint();public void mouseMoved(MouseEvent e)public void update(Graphics g) /重写update方法paint(g);10.4 项目实战一 键盘事件响应 1.实战内容在程序中通过对键盘事件响应实现移动按钮的功能;2.实战目的本实战要求读者运用前面所学的事件相关

328、知识,掌握如何在程序中实现对键盘事件进行响应。3.实战过程编程实现按上下左右光标键移动按钮的功能,程序代码如下:import java.awt.event.*;import javax.swing.*;public class kk extends JFrame implements KeyListener JButton JButton1;kk()JPanel jpanel1=new JPanel();JButton1=new JButton(按光标键移动我!);JButton1.addKeyListener(this);this.setSize(400,300);this.setDefau

329、ltCloseOperation(JFrame.EXIT_ON_CLOSE);jpanel1.add(JButton1);this.add(jpanel1);this.setVisible(true);public void keyPressed(KeyEvent e)int x,y;x=JButton1.getBounds().x;y=JButton1.getBounds().y;if(e.getKeyCode()=KeyEvent.VK_UP)y=y-5;if(y=240)y=240;if(e.getKeyCode()=KeyEvent.VK_LEFT)x=x-5;if(x=300)x=3

330、00;JButton1.setLocation(x,y);public void keyReleased(KeyEvent e)public void keyTyped(KeyEvent e)public static void main(String args)new kk();10.5 项目实战二 鼠标事件响应1.实战内容 在程序中通过鼠标事件进行响应实现单击左右键画变大变小的圆。2.实战目的 本实战要求读者运用前面所学的事件相关知识,熟练掌握如何在程序中实现对鼠标事件进行响应。3.实战过程下面程序是当鼠标左键时在当前位置画一个变大的圆,当按鼠标右键时画一个变小的圆。程序代码如下:impo

331、rt java.awt.event.*;import javax.swing.*;import java.awt.*;public class mm extends JFrame implements MouseListener int left=-1,right=-1;int x=-1,y=-1,d=20;JPanel jp=new JPanel();s.setSize(400,300);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.add(jp);this.setVisible(true);public void pain

332、t(Graphics g)if(left=1)d=d+10;g.drawOval(x,y,d,d);if(right=1)d=d-10;g.drawOval(x,y,d,d);JPanel jp=new JPanel();public mm()jp.addMouseListener(this);this.setSize(400,300);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.add(jp);this.setVisible(true);public void paint(Graphics g)if(left=1)d=d+

333、10;g.drawOval(x,y,d,d);if(right=1)d=d-10;g.drawOval(x,y,d,d);public void mouseReleased(MouseEvent e)public void mouseEntered(MouseEvent e)public void mouseExited(MouseEvent e)public void mouseClicked(MouseEvent e)public static void main(String args)new mm();项目小结 本项目重点介绍了事件处理机制和在程序中如何对键盘和鼠标操作进行响应,其中主

334、要介绍了如下内容:(1)Java事件处理机制。 Java事件处理采用授权处理机制,授权模型把事件委托给外部的处理实体进行处理,实现了将事件源和监视器分开的机制,要为每个事件源设置一个监视器。事件处理时涉及java.awt.event包与java.swing.event包中相关的类与接口。(2)对键盘事件的响应方法。 对键盘事件的响应主要使用java.awt.event.KeyListener接口中提供的方法来处理,还可以使用键盘适配器类KeyAdapter。(3)对鼠标事件的响应方法。 对鼠标事件的响应主要使用java.awt.event.MouseListener接口与java.awt.ev

335、ent. MouseMotionListener接口。本章小结本章小结 本章主要介绍了如下内容:1Java中事件处理机制JAVA事件处理中采用授权处理机制,授权模型把事件的处理委托给外部的处理实体进行处理,实现了将事件源和监视器分开的机制,要为每个事件源设置一个监视器。事件处理时涉及到java.awt.event包与java.swing.event包中相关的类与接口。 2对键盘事件响应方法对键盘事件响应主要使用java.awt.event.KeyListener接口中提供的方法来处理,还可以使用键盘适配器类KeyAdapter。 3对鼠标事件响应方法。对鼠标事件响应主要使用java.awt.e

336、vent.MouseListener接口与java.awt.event.MouseMotionListener接口。项目十一项目十一 数据库编程数据库编程任务一 :使用JDBC连接数据库任务二 :建立数据源任务三 :数据库编程项目实战一 数据库编程11.1 11.1 任务一任务一 使用使用JDBCJDBC连接数据库连接数据库11.1.1JDBC简介1JDBC概述JDBC(JavaDatabaseConnectivity,即Java数据库连接),是一种在Java应用程序中访问数据库的综合技术,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成,主要提供三方面的功能:建立同

337、数据库的连接,然后向数据库发送SQL语句,处理从数据库中返回的SQL执行结果。图4-1简单的条件语句 JDBC在Web和Internet应用程序中的作用和ODBC在 Windows系列平台应用程序中的作用类似,但ODBC只针对Windows平台,而且ODBC需要在客户机上安装和注册,因而维护成本相对较大。而JDBC是由Java语言编写的,使得JDBC代码可在所有Java平台上运行,这样使得程序的可移植性和安全性显著提高了。 应用程序通过相应接口(API)访问数据库,JDBC是Java应用程序访问数据库的通用接口,称为JDBC API。使用使用JDBCJDBC来完成对数据库的访问包括以下四个主要

338、组件:来完成对数据库的访问包括以下四个主要组件:Java的应用程序、JDBC驱动器管理器、驱动器和数据源。 图 11-1 JDBC框架图Java数据库应用程序JDBC驱动程序管理器JDBC驱动器数据库DBMSJDBC APIJDBC Driver APISQL命令 2 2JDBCJDBC的结构的结构(1)、面向应用程序设计的JDBC API:它主要是由一系列的接口组成,通过调用此API从而实现连接数据库、执行SQL语句并返回结果集等编程数据库的能力,如:java.sql.DriveManager:该接口主要定义了用来处理装载驱动程序并且为创建新的数据库连接提供支持。java.sql.Conne

339、ction:该接口主要定义了实现对某一种指定数据库连接的功能。java.sql.Statement:该接口主要定义了在一个给定的连接中作为SQL语句执行声明的容器以实现对数据库的操作。它主要包含有如下的两种子类型。java.sql.PreparedStatement:该接口主要定义了用于执行带或不带 IN 参数的预编译 SQL 语句。java.sql.CallableStatement:该接口主要定义了用于执行数据库的存储过程的雕用。java.sql.ResultSet:该接口主要定义了用于执行对数据库的操作所返回的结果集。(2)、面向数据库厂商的JDBCDriveAPI:数据库厂商必须提供相

340、应的驱动程序并实现JDBCAPI所要求的基本接口(每个数据库系统厂商必须提供对DriveManager、Connection、Statement、ResultSet等接口的具体实现),从而最终保证Java程序员通过JDBC实现对不同的数据库操作。11.1.2 JDBC11.1.2 JDBC驱动驱动目前比较常见的JDBC驱动程序可分为以下四个种类型: 1 1JDBC-ODBCJDBC-ODBC桥接桥接通过JDBC-ODBC桥接可以很容易地使用JDBC访问ODBC数据源。JDBC-ODBC 桥接方式是利用微软的开放数据库互连接口(ODBC API)同数据库服务器通讯的,它要求客户端上都要安装ODB

341、C驱动,同时还要求配置ODBC数据源。这种连接方式虽然简单但效率低。这种类型的驱动程序最适合于企业网络,或者是用Java编写的三层结构的应用程序服务器代码。2 2部分部分JavaJava的本地的本地APIAPI驱动程序驱动程序这种类型的驱动程序把客户机API上的JDBC调用转换为Oracle、Sybase、Informix、DB2或其它DBMS的调用。注意,象桥驱动程序一样,这种类型的驱动程序要求将某些二进制代码加载到每台客户机上。它比第一种驱动要快。3 3JDBCJDBC网络纯网络纯JavaJava驱动程序驱动程序 这种驱动程序将JDBC转换为与DBMS无关的网络协议,之后这种协议又被某个服

342、务器转换为一种DBMS协议。这种网络服务器中间件能够将它的纯Java客户机连接到多种不同的数据库上。所用的具体协议取决于提供者。通常,这是最为灵活的JDBC驱动程序。此种驱动很适合Internet应4 4本地协议纯本地协议纯JavaJava驱动程序驱动程序 11.2 11.2 任务二任务二 建立数据源建立数据源11.2.1 11.2.1 建立建立AccessAccess数据库数据库1 1ACCESSACCESS数据库的设计数据库的设计 在设计数据库时要确定设计数据库的目的、库中需要的表及表中需要的字段。每张表只包含关于一个主题的信息,在设计表时,应注意: 明确有唯一值的字段 确定表间的关系优化

343、设计 添加数据和新建其他数据库对象 根据用户需求,表的结构设计完成后,就可以继续创建所需的任何查询、窗体、报表、宏和模块等。 2 2表的创建及操作表的创建及操作 Access提供了四种创建空表的方法: (1)、使用数据库向导,可以在一个操作中创建整个数据库所需的全部表、窗体及报表。数据库向导用于新建数据库,但不能用来将新表、窗体或报表添加到已有的数据库中。 (2)、使用表向导来选择表的字段,这些字段可以从各种各样预先定义好的表中选择。 (3)、将数据直接输入到空白的数据表中。当保存新的数据表时,Access将分析数据并且自动为每一字段指定适当的数据类型及格式。 (4)、使用“设计”视图从无到有

344、指定表的全部细节。创建了数据表后,可以针对表进行添加记录 、定位记录 、编辑数据 、插入记录、选择记录、删除记录和记录的复制等操作了。11.2.2 11.2.2 建立数据源建立数据源1在window xp系统中,单击【开始】-【设置】-【控制面板】-【管理工具】 。2在弹出的窗口中双击打开【数据源ODBC】应用程序图标,再在打开的【ODBC数据源管理器】窗口中选择【系统DSN】标签。3单击【添加】按钮,在弹出的对话框中选择【Microsoft Access Driver (*.mdb) 】标签。4点击【完成】后,在弹出的Access数据源设置对话框中,输入【数据源名】为”mylibDB”,然后

345、单击【选择】按钮,找到刚才建立的数据库(即E盘jpp文件夹下的library.mdb文件),选中它并确定即可。(如果想设置访问密码,可以单击【高级】按钮,会弹出“高级设置选项”对话框)。 5单击确定后,ODBC数据源的设置就完成了。11.3 11.3 任务三任务三 数据库编程数据库编程11.3.1 11.3.1 数据库编程过程数据库编程过程1 1JDBCJDBC数据库编程用到的相关类和接口数据库编程用到的相关类和接口(1)、DriverManager类:负责管理JDBC驱动程序。使用JDBC驱动程序之前,必须先将驱动程序加载并向DriverManager注册后才可以使用,同时提供方法来建立与数

346、据库的连接。方法如下:Class.forName(Stringdriver):加载注册驱动程序。StaticConnectiongetConnection(Stringurl,Stringuser,Stringpassword) throwsSQLException:取得对数据库的连接。StaticDrivergetDriver(Stringurl)throwsSQLExcetion:在已经向DriverManager注册的驱动程序中寻找一个能够打开url所指定的数据库的驱动程序。(2)、Connection类Connection对象是通过DriverManager.getConnection

347、()方法获得的,主要负责维护JSP/JAVA数据库程序和数据库之间的联机,建立Java程序与数据库之间的连接,并生成三个非常有用的类对象:Statement类对象、DatabaseMetaData类对象和PreparedStatement类对象。建立Statement类对象的方法如下:StatementcreateStatement()throwsSQLException;StatementcreateStatement(intresultSetType,intresultSetConcurrency)throwsSQLException;建立DatabaseMetaData类对象的方法如下:

348、DatabaseMetaDatagetMetaData()throwsSQLException;建立PreparedStatement类对象的方法如下:PreparedStatementprepareStatement(Stringsql)throwsSQLException;(3)、Statement类Statement类用于将SQL语句发送到已连接的数据库中,通过Statement类所提供的方法(见表11-4),可以利用标准的SQL命令,对数据库直接新增、删除或修改等操作。(4)、PreparedStatement类PreparedStatement类和Statement类的不同之处在于P

349、reparedStatement类对象会将传入的SQL命令事先编好等待使用,当有单一的SQL指令比多次执行时,用PreparedStatement类会比Statement类有效率。 (5)、DatabaseMetaData类 DatabaseMetaData类保存了数据库的所有特性,并且提供许多方法(见表11-6)来取得这些信息。(6)、ResultSet类ResultSet类是Statement类招待SQL语句后生成的记录集。可以认为它是一个二维的表格,主要负责存储查询数据库的结果。并提供一系列的方法(见表11-7)对数据库进行新增、删除和修改操作。也负责维护一个记录指针(Cursor),记

350、录指针指向数据表中的某个记录,通过适当的移动记录指针,可以随心所欲的存取数据库,加强程序的效率。(7)、ResultSetMetaData类ResultSetMetaData类对象保存了所有ResultSet类对象中关于字段的信息,提供许多方法(见表11-8)来取得这些信息:2. 2. 数据库访问过程数据库访问过程(1)、 首先装载驱动程序 装载驱动程序DriverManager类使用Class类的forName方法。语法如下: Class.forName()或Class.forName().newInstance() 根据需要装载的驱动的不同,具体方法也不同。这里是加载ODBCJDBC桥接的

351、例子: String jdbcDriver=sun.jdbc.odbc.JdbcOdbcDriver try Class.forName(jdbcDriver); catch(java.lang.ClassNotFoundException e) System.out.println(类未找到错误!+e); 注意注意: : 装载驱动程序要处理异常。装载驱动程序要处理异常。(2)、 建立连接 指定装载的数据库驱动程序后,可用DriverManager类来进行数据源或数据库的连接。DriverManager类是JDBC基础,用来管理JDBC驱动程序。该类有静态的getConnection()方法,

352、用于验证JDBC数据源,并返回接口Connection对象。 使用JDBCODBC桥接器的例子: Connection con = DriverManager.getConnection (jdbc:odbc:mylibDB); 其中的mylibDB为建立的数据源的名称。根据需要装载的驱动的不同,具体的连接方法也不同。A、这里是加载mySQL JDBC驱动程序 Class.forName(org.gjt.mm.mysql.Driver ).newInstance(); String url=jdbc:mysql:/localhost/myDB? user=mymouse&password=mo

353、use2008&useUnicode=true&characterEncoding=8859_1 Connection con=DriverManager.getConnection(url) B、装载Oracle JDBC OCI驱动程序(用thin模式) Class.forName(oracle.jdbc.driver.OracleDriver ); String url=jdbc:oracle:thin:localhost:1521:orcl“;String user=bigmouse;String password=mouse;Connection con=DriverManager.

354、getConnection(url,user,password);注意:也可以通过con.setCatalog(MyDatabase)来加载数据库。 C、装载DB2驱动程序Class.forName(COM.ibm.db2.jdbc.app.DB2Driver ) String url=jdbc:db2:/localhost:5000/mydata;/ mydata为你的数据库名 String user=admin; String password=; Connection con= DriverManager.getConnection(url,user,password); D、装载Mic

355、roSoft SQLServer驱动程序Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver);String url=jdbc:microsoft:sqlserver:/localhost:1433;DatabaseName=bookstore; / bookstore为你的数据库 String user=book; String password=; Connection con= DriverManager.getConnection(url,user,password); (3)、 获取数据库信息和创建接口Statement

356、对象 数据库连接成功后,可以使用Connection对象的getMetaData方法取得接口DatabaseMetaData(提供大量的方法)对象来了解数据源或数据库的各种信息。数据库连接成功后,还可以使用向数据库发送访问数据库的SQL语句的方法来存取数据库。JDBC使用接口Statement的对象(或执行数据库存储过程的子接口CallableStatement、发送带参数的SQL语句的子接口PreparedStatement)来发送SQL语句,Statement对象可用Connection的方法createStatement()来返回。例如: Statement st = con.creat

357、eStatement(); (4)、 执行SQL语句以存取数据库 希望执行的SQL语句串作为Statement的方法execute()等的参数向数据库传送,以交给数据库引擎,执行SQL对数据库的访问操作。对数据库访问结果是一个数据表的情况,可将这个表(结果集)存入接口ResultSet的对象。 提交SQL语句的Statement的方法有execute、executeQuery和executeUpdate等,分别用于不同类型的SQL语句的提交。 executeQuery:用于产生单个结果集的语句,如查询语句select。 executeUpdate:用于执行不产生结果集的语句,如insert,d

358、elete,update等。 execute:可用于执行产生多个结果集或对数据库进行多个操作的SQL语句。 (5)、 对执行SQL语句的结果进行处理 Statement对象将SQL语句封装起来交给数据库引擎,执行select查询语句,将得到结果集ResultSet对象(注意:执行insert、delete、update等查询语句无结果集)。 接口ResultSet对象封装了执行SQL语句的返回结果,以后可根据需要,以便在屏幕上显示结果或做进一步的处理。 在执行select语句后的返回结果中,包含了数据表和数据表内容的相关信息。关于数据表的信息可通过ResultSet的getMetaData方法

359、来创建ResultSetMetaData对象,由这个对象可获取所需数据库的信息。 例如: ResultSetMetaData rsmd = rs.getMetaData(); rsmd.getColumnCount() / 获取列(字段)数 rsmd.getColumnName(列号) / 获取指定列(字段)的列名 在ResultSet中,提供了一整套的getXXX方法(如getInt,getString,getFloat,getDouble等)来访问结果集中当前行的不同列(用列序号或列标题作为这些方法的参数)的数据(类型不同时可将字段类型按照XXX类型来进行类型转换),而next方法可使得访

360、问可对不同的行来进行。 例如,可用下面的程序段对book表的书名(name)和作者(author)进行访问: ResultSet rs = st.executeQuery( “select name,author from book); while(rs.next() System.out.println(rs.getString(name) + + rs.getString(3); ResultSet自动维护结果集当前数据行的指向光标,首先获得结果集时,指向光标置于结果集的第一行前,以后每调用一次next方法,光标就向下移动一行,这样可按照顺序从第一行到最后一行逐行访问结果集的每一行(访问结

361、束时next返回false值)。 在有些情况下,可能希望任意访问而不是顺序访问结果集的数据行,对某些结果集,可能还希望通过结果集修改数据库的数据,则应在createStatement 方法中加入如下的两个参数,即: Statement st = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);如果只希望任意滚动结果集的指向光标,而不修改数据库的数据,则可在上述两个参数中将第二个参数设置为ResultSet.CONCUR_READ_ONLY。 通过参数的设置,就可以用Resul

362、tSet的first,last,previous,absolute,relative等方法来设置当前行,并且还可以根据参数的更新设置,用insertRow(插入行)、deleteRow(删除行)、updateRow(更新行)等方法来对数据库表进行增、删、改的操作。(6)、 关闭连接 数据库访问结束,为保证数据库数据的完整性和释放系统资源,应明确地关闭数据库的连接:一般是关闭结果集、关闭数据库访问对象和关闭连接。11.3.2 11.3.2 数据库编程实例数据库编程实例1 1查询数据库举例查询数据库举例利用前面创建的数据库利用前面创建的数据库library.MDBlibrary.MDB和数据源和数

363、据源mylibDBmylibDB来对数据来对数据库中的表库中的表bookbook进行查询,显示表中所有图书的编号(进行查询,显示表中所有图书的编号(nono)、)、书名书名(name)(name)、作者(、作者(authorauthor)、出版日期()、出版日期(printdateprintdate)和版)和版次(次(timestimes)。)。【例【例11-211-2】查询数据库举例。】查询数据库举例。import java.sql.*;class jdbccxpublic static void main(String args)tryClass.forName(sun.jdbc.odbc

364、.JdbcOdbcDriver);catch(ClassNotFoundException ce)System.out.println(SQLException:+ce.getMessage();tryConnection conn=DriverManager.getConnection(jdbc:odbc:mylibDB);Statement stmt=conn.createStatement();ResultSet rs=stmt.executeQuery(select * from book);while(rs.next()System.out.println(“编号:”+rs.getS

365、tring(“no”)+“t”+ “书 名:+rs.getString(name)+t+作者:+rs.getString (author)+t+出版日期:+rs.getDate(4)+t+印刷次数:+rs.getInt(5)+t+价格:+rs.getFloat(6); rs.close(); stmt.close(); catch(SQLException ce)System.out.println(SQLException+ce.getMessage(); 【程序解析】【程序解析】(1)、首先引入包:java.sql中的所有类。(2)、利用查询语句:select*from book查询表中的

366、记录,查询结果保存在结果集rs中。(3)、通过while循环,将查询结果中的每一行记录显示在屏幕上。(4)、 取得rs中的列值时,可以使用方法getXXX(列名),如程序中的rs.getString(“no”);表示取得列名为“no”的数据。XXX取决于该列的数据类型。如果该列为字符串型,则使用getString(),如果该列为整型,则使用getInt(),如果该列为浮点型,则使用getFloat()。(5)、有时候,使用方法getXXX(列名)时,参数可以不使用列名,可以使用列的序号。(6)、注意捕获例外,见程序中的几种例外类型。(7)、程序中,在while循环体中“t”表示水平制表(8)、

367、在实际查询中,往往只要查询数据库中的一些特定数据,而不要查询整个表中的所有记录,使用参数查询数据库可以实现按条件查询,SQL查询语句SELECT中,应用条件选项WHERE实现有条件地查询。 2 2插入记录举例插入记录举例通过通过JavaJava程序,可以向数据库中的表程序,可以向数据库中的表studentstudent中插入记录。中插入记录。 见书【例见书【例11-311-3】插入记录举例。】插入记录举例。【程序解析】(1)、插入记录使用方法是executeUpdate(),此方法不产生结果集。(2)、需要注意的是:向表中插入记录只允许插入不重复的记录。(3)、A行也可以改成:Prepared

368、Statement pstmt=conn.prepareStatement(insert into book values(?,?,?,?,?,?);pstmt.setString(1,85492);pstmt.setString(2,java2实务);pstmt.setString(3,杜江);pstmt.setDate(4,Date.valueOf(2008-12-12);pstmt.setInt(5,4);pstmt.setFloat(6,34.5f);pstmt.executeUpdate();用PreparedStatement语句时,可使用“占位符”?来表示SQL命令中可变部分提高

369、效率。setXXX()方法中的第一个参数是所对应“?”的参数序号,第二个参数是“?”代表的参数的值。3 3修改记录举例修改记录举例修改表book中的第1条记录:将java程序设计的no改为20090110。【例【例11-411-4】修改记录举例。】修改记录举例。4 4删除记录举例删除记录举例【例【例11-511-5】将表】将表bookbook中的作者是杜江的图书记录。中的作者是杜江的图书记录。5 5建立表举例建立表举例不但可以在数据库中创建表,也可以在程序中通过JDBC来建立一个新表,建立表包括建立的表的结构和记录。例如,建立表publishing,表结构有press(出版社)和num(销量)

370、,然后向表中插入如下两条记录:清华大学 ,120000000中国水利水电,110000000【例【例11-611-6】建立表举例。】建立表举例。import java.sql.*;class jdbcjianlibiaopublic static void main (String args)tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver);catch(ClassNotFoundException ce)System.out.println(SQLException:+ce.getMessage();tryConnection conn=Driver

371、Manager.getConnection(jdbc:odbc:mylibDB);Statement stmt=conn.createStatement();/建立表的表结构/stmt.executeUpdate(delete table publishing);String sql=create table publishing(press char(40),num long);stmt.executeUpdate(sql);/插入两条记录sql=insert into publishing (press,num)values(清华大学,120000000);/stmt.executeUpd

372、ate(sql);sql=insert into publishing values(中国水利水电,110000000);stmt.executeUpdate(sql);/显示查询结果ResultSet rs=stmt.executeQuery(select * from publishing);while(rs.next() System.out.println(出版社:+rs.getString(press)+t+ 销售数量:+rs.getInt(num); rs.close(); stmt.close(); catch(SQLException ce) System.out.printl

373、n(SQLException:+ce.getMessage(); 11.4 11.4 项目实战一项目实战一 数据库编程数据库编程 1.实战内容 本实战要求读者编写一个有关JDBC数据库技术的应用程序,实现数据库的添加、删除、修改等简单操作。运用前面所用的编程技能,正确地编写此应用程序。 2.实战目的 通过实战掌握JDBC访问数据库和数据连接的基本方法,掌握数据库添加、删除、修改、查询等操作方法。 3.实训过程 编写程序,在数据库“职工”中创建一个表名为“职工登记”的应用程序,并将创建的表显示到屏幕上,如图11-12所示。要求数据库的数据用人机对话的方式输入。(1 1)建表建表。 启动启动Acc

374、essAccess程序,在程序,在AccessAccess数据库中创建数据库中创建“职工职工”数数据库。据库。 (2 2)配置环境配置环境。 将将JDBCJDBCODBCODBC桥驱动配置好,并连接数据源。桥驱动配置好,并连接数据源。 (3 3)编写代码编写代码。 这些实验都需要用到表格显示数据,因此这些实验都需要用到表格显示数据,因此要要设计一个设计一个RSTable.javaRSTable.java文件封装表格显示功能。文件封装表格显示功能。本章小结本章小结 本章首先介绍了JDBC的基本概念及JDBC的工作原理,掌握了四种JDBC驱动程序类型及JDBC API 几个重要的类及接口,重点介绍数据库的连接及编程过程,学会用几个重要的对象编写加载数据库驱动和连接数据库的Java程序和应用Javasql包中的类和接口编写操作数据库的应用程序。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号