Java 游戏编程导学 陆光义 宋现锋 编著 清 华 大 学 出 版 社 北 京 前 言 对于一个软件开发人员来说,当前发展最快的主流计算机语言就是由Sun公司开发的 Java语言。Java语言,因为它的简单易用、平台无关性和健壮性,在短短10年时间之内,很 快就发展成为当前最流行的编程语言。同时,为了适应企业应用和嵌入式系统开发,Sun 公司推出了相应的J2EE和J2ME开发工具包和响应规范。目前,它们已经成为各自相关领域 内的主流产品。在当今的网络时代,学习Java,掌握Java编程,对程序员来说不再是可有可 无,Java已经成为开发人员必备的工具了。 本书讲解Java语言的基本知识和应用,这同时也是J2EE和J2ME应用开发的基础。 本书的内容 本书首先介绍了Java基础知识,之后每章将介绍一个或多个精心制作的趣味游戏,它 们各自侧重于应用Java语言的某些特性,循序渐进,详细讲述了Java语言,并给出大量示例 和非常有价值的编程方法。 第1章介绍了Java特性和一些基本语法。在这一章,读者可以了解到Java的历史、现状 及其发展前景,同时也将学会如何编写和运行一个简单的“Hello World”Java程序。 第2章先讲解Java面向对象编程的一些基本概念,然后通过“幸运52”模拟游戏的编写, 让读者对Java的面向对象编程有更深的理解。 第3章讲解了持有对象和异常处理的知识,同时编写了“球迷必答”和“速算24”游戏。 在“球迷必答”游戏中,用户被询问5道问题,前一道问题必须答对,方可进入下一道问题。 在“速算24”游戏中,用户随意抽出4张扑克牌,用加、减、乘、除的方法将它们连接起来, 使得结果等于24。这一章通过这两个游戏来加深读者对数据结构、异常处理等知识的理解。 第4章通过“精彩闹钟”和“模拟钢琴”游戏,重点讲解Java在图形和多媒体方面的一 些简单应用,AWT的组件编程,也涉及到事件处理及简单的动画处理等内容。 第5章的“拼图”游戏和文曲星里的拼图游戏类似。这一章接着上一章,继续讲述Java 的图形和多媒体应用,以及Applet的知识和多线程技术等内容。 第6章通过编写“记事本”和“弹球”游戏,来介绍Java语言编程中的Swing包和I/O知 识。Swing包基本已经取代AWT包,成为目前最流行的GUI编程技术;I/O知识是程序本地 化必不可少的条件。 第7章编写了一个“俄罗斯方块”游戏,我们要编写的俄罗斯方块是一个应用程序(Java Application),不再是嵌到网页里的那种小应用程序(Applet)。游戏设计过程中涉及到游 戏框架、游戏界面的编写,菜单处理、变量的定义、算法设计以及预览功能的实现。通过 这一章,读者可以领略到Java的整体编程风格。同时,我们还为游戏添加了其他功能,如 设计About对话,实现游戏分数的存档,为游戏添加状态栏等。在此我们可以学到如何定义 类和类成员及其方法,如何使用JBuilder来创建一个对话框,并将对话框和主应用程序联系 起来。 在第8章中,我们将把这个游戏改编为网络俄罗斯方块游戏,并使用了最新的Java 2标 准Swing组件,使得界面更具有专业效果。本章主要讲解游戏的网络实现,使游戏能够实现 多用户网络对战,其中涉及到网络模块的编写,ServerSocket的使用,如何实现服务器/客户 间即时通信,NetRead接口的定义,聊天界面的设计,网络协议的设计,网络连接的实现及 如何将游戏打包并发布。通过这些内容让读者领略Java强大的网络功能,学习Java的网络编 程技巧。 本书在选题、策划及编写时,努力做到以下几点: · 趣味性 · 直观性 · 可操作性 · 循序渐进 我们将电脑游戏和程序设计这两个精彩的世界嫁接在一起,希望读者能在充满趣味的 学习过程中轻松地入门,尝试编程的乐趣,以便尽早掌握这一现代编程工具。 本书所附光盘的使用说明 随本书带有一张光盘。光盘中含有本书中涉及到的全部示例的源代码及各种资源文件, 以方便读者在学习过程中查阅、参考。 编 者 2004年10月 内 容 提 要 本书通过编写趣味游戏程序来引导读者学习 Java 编程的方法和技巧,形式新颖活泼,别具一格。 全书从 Java 语言基础知识和编制简单的程序入手,将 Java 编程的知识点有机地分散在“幸运 52”,“速 算 24”,“俄罗斯方块”等多个趣味游戏的程序设计示例中,使得 Java 语言中类、对象、属性、方法、接 口、继承等抽象概念变得具体形象,通俗易懂;并引导读者掌握 Java 中数组、字符串、事件处理、异常 处理、图形和多媒体应用、Swing 组件和网络等知识的运用和技巧。 本书以示例教学方式来组织内容,集趣味性、直观性、可操作性于一体,适合于 Java 初学者及对游 戏程序感兴趣的电脑爱好者阅读参考。 版权所有,翻印必究。举报电话:010-62782989 13901104297 13801310933 本书封面贴有清华大学出版社激光防伪标签,无标签者不得销售。 图书在版编目(CIP)数据 Java 游戏编程导学/陆光义,宋现锋编著. —北京:清华大学出版社,2004 ISBN 7-302-09776-3 Ⅰ. J… Ⅱ. ①陆… ②宋… Ⅲ. JAVA 语言—程序设计 Ⅳ. TP312 中国版本图书馆 CIP 数据核字(2004)第 108635 号 出 版 者:清华大学出版社 地 址:北京清华大学学研大厦 http://www.tup.com.cn 邮 编:100084 社 总 机:010-62770175 客户服务:010-62776969 组稿编辑:科海 文稿编辑:洪英 封面设计:林陶 版式设计:科海 印 刷 者:北京市耀华印刷有限公司 发 行 者:新华书店总店北京发行所 开 本:787×1092 1/16 印张:23.5 字数:572 千字 版 次:2004 年 11 月第 1 版 2004 年 11 月第 11 次印刷 书 号:ISBN 7-302-09776-3/TP·6750 印 数:1~5000 定 价:35.00 元(1CD) 本书如存在文字不清、漏印以及缺页、倒角、脱页等印装质量问题,请与清华大学出版社出版部联系 调换。联系电话:82896445 目 录 第1章 Java基础 ............................................................................................................. 1 1.1 Java简介 ................................................................................................................................................ 1 1.1.1 Java的历史.................................................................................................................................... 1 1.1.2 Java的特性.................................................................................................................................... 2 1.1.3 Java的应用.................................................................................................................................... 4 1.1.4 J2SE 1.5的新特性......................................................................................................................... 4 1.2 Java语言基本概念 ................................................................................................................................6 1.2.1 基本数据类型............................................................................................................................... 6 1.2.2 数组............................................................................................................................................. 11 1.2.3 运算符和表达式......................................................................................................................... 13 1.2.4 基本控制语句............................................................................................................................. 17 1.3 编写和运行Java程序 .......................................................................................................................... 25 1.3.1 Java开发工具简介...................................................................................................................... 25 1.3.2 Hello World................................................................................................................................. 26 1.3.3 编译和运行................................................................................................................................. 26 1.4 本章知识点回顾 ................................................................................................................................. 27 第2章 面向对象编程起步 ............................................................................................. 32 2.1 类和对象 ............................................................................................................................................. 32 2.1.1 类................................................................................................................................................. 32 2.1.2 对象............................................................................................................................................. 34 2.1.3 一个小问题——static................................................................................................................. 35 2.2 类的继承和多态 ................................................................................................................................. 36 2.2.1 Java的继承.................................................................................................................................. 36 2.2.2 abstract类和接口 ........................................................................................................................ 38 2.2.3 多态............................................................................................................................................. 40 2.3 包......................................................................................................................................................... 41 2.3.1 包的定义..................................................................................................................................... 41 2.3.2 包的使用..................................................................................................................................... 41 2.3.3 对包内类的访问权限................................................................................................................. 42 2.4 “幸运52”游戏 ................................................................................................................................. 43 2.4.1 游戏效果说明............................................................................................................................. 43 2.4.2 编写HTML页面.......................................................................................................................... 44 2.4.3 编写Java代码.............................................................................................................................. 45 2.4.4 程序在JBuilder中的编写 ........................................................................................................... 55 2.5 进一步实践 ......................................................................................................................................... 60 2 目 录 2.6 本章知识点回顾 ................................................................................................................................. 60 第3章 持有对象与异常处理.......................................................................................... 64 3.1 持有你的对象 ..................................................................................................................................... 64 3.1.1 Array(数组) ........................................................................................................................... 64 3.1.2 Collection(集合) .................................................................................................................... 64 3.1.3 Mapping(映射) ...................................................................................................................... 68 3.2 “球迷必答” ..................................................................................................................................... 70 3.2.1 游戏规则..................................................................................................................................... 70 3.2.2 游戏注意点................................................................................................................................. 70 3.2.3 建立工程..................................................................................................................................... 71 3.2.4 编写问题封装文件QuestionBean............................................................................................... 72 3.2.5 编写游戏界面............................................................................................................................. 73 3.2.6 处理事件..................................................................................................................................... 76 3.2.7 使用UI编辑器来编写消息对话框............................................................................................. 77 3.3 异常处理机制 ..................................................................................................................................... 81 3.3.1 基本异常..................................................................................................................................... 81 3.3.2 捕获异常..................................................................................................................................... 82 3.3.3 重新抛出异常............................................................................................................................. 85 3.3.4 标准Java异常.............................................................................................................................. 85 3.3.5 创建自己的异常......................................................................................................................... 86 3.4 “速算24”游戏 ................................................................................................................................. 87 3.4.1 游戏效果说明............................................................................................................................. 87 3.4.2 编写游戏规则............................................................................................................................. 88 3.4.3 创建工程和Applet...................................................................................................................... 88 3.4.4 设计游戏界面............................................................................................................................. 90 3.4.5 增加对表达式处理的方法......................................................................................................... 97 3.4.6 添加对Applet中按钮的事件处理 .............................................................................................. 99 3.4.7 进一步实践............................................................................................................................... 101 3.5 本章知识点回顾 ............................................................................................................................... 101 第4章 Java编程深入——图像与多媒体...................................................................... 105 4.1 AWT简介 .......................................................................................................................................... 105 4.2 布局管理器 ....................................................................................................................................... 106 4.2.1 FlowLayout ............................................................................................................................... 106 4.2.2 BorderLayout ............................................................................................................................ 107 4.2.3 GridLayout ................................................................................................................................ 107 4.2.4 CardLayout................................................................................................................................ 107 4.3 图像简介 ........................................................................................................................................... 108 4.3.1 文件格式................................................................................................................................... 108 4.3.2 图像的创建、加载和显示....................................................................................................... 108 4.3.3 ImageObserver .......................................................................................................................... 109 目 录 3 4.3.4 MediaTracker ............................................................................................................................ 111 4.3.5 Graphics类 ................................................................................................................................ 112 4.4 事件处理 ........................................................................................................................................... 114 4.4.1 事件处理机制........................................................................................................................... 114 4.4.2 事件类....................................................................................................................................... 115 4.4.3 事件监听器接口....................................................................................................................... 115 4.5 “精彩闹钟” ................................................................................................................................... 117 4.5.1 程序效果说明........................................................................................................................... 117 4.5.2 实现简单的界面....................................................................................................................... 117 4.5.3 画出表盘和表针....................................................................................................................... 123 4.5.4 让闹钟动起来........................................................................................................................... 125 4.5.5 给闹钟加上声音....................................................................................................................... 126 4.6 “模拟钢琴”游戏 ........................................................................................................................... 128 4.6.1 游戏效果说明........................................................................................................................... 128 4.6.2 实现简单的界面....................................................................................................................... 129 4.6.3 添加事件处理........................................................................................................................... 133 4.6.4 继续完善这个游戏................................................................................................................... 137 4.6.5 加上音响效果........................................................................................................................... 142 4.6.6 鼠标拖动时实现琴键的自动按下和释放 ............................................................................... 144 4.6.7 动画效果的改进....................................................................................................................... 148 4.6.8 Java的局限................................................................................................................................ 149 4.7 本章知识点回顾 ............................................................................................................................... 149 第5章 拼图游戏——Applet和线程.............................................................................. 156 5.1 Applet基础 ........................................................................................................................................ 156 5.1.1 Applet简介................................................................................................................................ 156 5.1.2 Applet体系结构........................................................................................................................ 156 5.1.3 Applet框架................................................................................................................................ 157 5.1.4 其他一些有用的方法............................................................................................................... 158 5.1.5 AppletContext接口的主要方法................................................................................................ 159 5.2 线程技术 ........................................................................................................................................... 159 5.2.1 继承线程................................................................................................................................... 160 5.2.2 Thread和Runnable .................................................................................................................... 161 5.2.3 线程的优先级........................................................................................................................... 162 5.2.4 线程同步................................................................................................................................... 164 5.2.5 多线程技术............................................................................................................................... 164 5.3 “拼图”游戏 ................................................................................................................................... 165 5.3.1 游戏的简单设计....................................................................................................................... 166 5.3.2 实现简单的界面....................................................................................................................... 166 5.3.3 事件处理................................................................................................................................... 172 5.3.4 让游戏能够判断游戏当前状态,并能重新开始.................................................................... 180 5.3.5 让游戏的每次初始化状态都不一样 ....................................................................................... 182 4 目 录 5.3.6 消除闪烁问题........................................................................................................................... 183 5.3.7 让游戏记录玩家所用的时间,并计算出分数 ....................................................................... 183 5.3.8 利用多线程技术来实现计时器,记录玩家玩的时间............................................................ 184 5.3.9 用F1键重新开始游戏............................................................................................................... 186 5.3.10 利用HTML的param标记来改变不同的图片 ........................................................................ 187 5.3.11 增加预览的功能..................................................................................................................... 193 5.3.12 加入音响效果......................................................................................................................... 196 5.3.13 CGI程序——进一步实践 ...................................................................................................... 197 5.4 本章知识点回顾 ............................................................................................................................... 200 第6章 Swing和I/O简介............................................................................................... 203 6.1 Swing组件简介 ................................................................................................................................. 203 6.1.1 JApplet ...................................................................................................................................... 203 6.1.2 按钮类....................................................................................................................................... 203 6.1.3 JComboBox............................................................................................................................... 210 6.1.4 滚动窗格................................................................................................................................... 210 6.1.5 树............................................................................................................................................... 210 6.1.6 表格(JTable) ........................................................................................................................ 211 6.2 I/O系统.............................................................................................................................................. 213 6.2.1 输入和输出............................................................................................................................... 213 6.2.2 FilterInputStream和FilterOutputStream.................................................................................... 215 6.2.3 File ............................................................................................................................................ 216 6.2.4 Java1.1的I/O流 ......................................................................................................................... 218 6.2.5 几个比较重要的类................................................................................................................... 218 6.3 “记事本”程序示例........................................................................................................................ 222 6.3.1 建立工程和框架文件............................................................................................................... 223 6.3.2 完成界面的设计....................................................................................................................... 224 6.3.3 添加“文件”主菜单事件响应 ............................................................................................... 229 6.3.4 添加“编辑”和“关于”主菜单的事件响应 ....................................................................... 232 6.3.5 添加按钮的事件....................................................................................................................... 233 6.4 “弹球”游戏 ................................................................................................................................... 234 6.4.1 游戏的简单设计....................................................................................................................... 234 6.4.2 实现简单的界面....................................................................................................................... 234 6.4.3 让小球运动起来....................................................................................................................... 238 6.4.4 事件处理——让游戏能够玩起来 ........................................................................................... 242 6.4.5 让游戏能够判断当前状态,并能重新开始 ........................................................................... 243 6.4.6 让游戏记录玩家的生命,并计算出分数 ............................................................................... 244 6.4.7 加入音响效果........................................................................................................................... 245 6.5 本章知识点回顾 ............................................................................................................................... 246 第7章 俄罗斯方块游戏——综合应用示例 .................................................................. 254 7.1 游戏效果说明 ................................................................................................................................... 254 目 录 5 7.2 游戏的简单设计 ............................................................................................................................... 255 7.3 编写游戏框架 ................................................................................................................................... 255 7.3.1 编写游戏框架........................................................................................................................... 255 7.3.2 为游戏编写菜单项................................................................................................................... 258 7.3.3 为菜单增加事件处理............................................................................................................... 261 7.4 开始编写游戏界面 ........................................................................................................................... 264 7.4.1 在Panel中加入几个必要的常量和变量 .................................................................................. 264 7.4.2 在Panel上画出游戏界面 .......................................................................................................... 265 7.4.3 将Panel加到框架里去.............................................................................................................. 267 7.5 开始编写游戏内容 ........................................................................................................................... 267 7.5.1 定义一个方块类....................................................................................................................... 267 7.5.2 定义描述游戏状态的变量....................................................................................................... 268 7.5.3 初始化游戏状态....................................................................................................................... 269 7.5.4 编写产生新的方块组的算法 ................................................................................................... 269 7.5.5 编写方块组移动的算法........................................................................................................... 271 7.5.6 编写将一行消去的算法........................................................................................................... 273 7.5.7 在游戏里实现一个线程........................................................................................................... 273 7.5.8 控制游戏开始........................................................................................................................... 274 7.5.9 让游戏暂停............................................................................................................................... 275 7.5.10 让游戏结束............................................................................................................................. 276 7.5.11 判断游戏是否结束................................................................................................................. 276 7.5.12 让玩家控制游戏——添加事件处理 ..................................................................................... 276 7.5.13 重新编写画图的功能代码..................................................................................................... 278 7.5.14 类的同步方法......................................................................................................................... 279 7.5.15 计算游戏的得分和当前游戏级别 ......................................................................................... 280 7.6 添加游戏的其他功能........................................................................................................................ 280 7.6.1 设计About对话框..................................................................................................................... 280 7.6.2 设计设定游戏等级的对话框 ................................................................................................... 285 7.6.3 为游戏添加状态栏................................................................................................................... 289 7.7 封装得分情况 ................................................................................................................................... 290 7.7.1 定义Score类和类成员.............................................................................................................. 290 7.7.2 定义方法writeToFile() ............................................................................................................. 291 7.7.3 定义方法readFromFile()........................................................................................................... 293 7.7.4 定义方法sortScore() ................................................................................................................. 294 7.7.5 定义方法isScoreTop(int nScore).............................................................................................. 294 7.7.6 定义方法insertNameScore(String sName,int nScore) .............................................................. 295 7.7.7 定义方法getScore()和getName() ............................................................................................. 295 7.8 编写对话框,让玩家输入名字........................................................................................................ 296 7.8.1 输入玩家名字的对话框........................................................................................................... 296 7.8.2 查看排名榜的对话框............................................................................................................... 298 7.9 本章知识点回顾 ............................................................................................................................... 301 6 目 录 第8章 网络俄罗斯方块游戏——Swing组件与网络功能.............................................. 304 8.1 游戏效果说明 ................................................................................................................................... 304 8.2 游戏的简单设计 ............................................................................................................................... 306 8.3 编写简单的网络模块........................................................................................................................ 307 8.3.1 网络的基本概念....................................................................................................................... 307 8.3.2 ServerSocket简介...................................................................................................................... 309 8.3.3 Socket简介................................................................................................................................ 310 8.3.4 InetAddress类方法简介............................................................................................................ 310 8.3.5 简单的服务器端实现............................................................................................................... 311 8.3.6 简单的客户端实现................................................................................................................... 318 8.3.7 用两个端口实现即时通信....................................................................................................... 319 8.3.8 定义接口NetRead..................................................................................................................... 325 8.3.9 如何使用这个模块——server包和client包............................................................................. 326 8.4 改编游戏框架 ................................................................................................................................... 326 8.4.1 让界面画出两个游戏区域....................................................................................................... 327 8.4.2 增加菜单及其事件处理功能 ................................................................................................... 329 8.4.3 连接对方的对话框设计........................................................................................................... 331 8.4.4 设计聊天界面........................................................................................................................... 333 8.4.5 编写显示双方分数的对话框 ................................................................................................... 335 8.4.6 编写警告对方不能运行某个命令的提示框 ........................................................................... 337 8.5 把网络模块加入到游戏之中............................................................................................................ 340 8.5.1 网络协议的设计....................................................................................................................... 340 8.5.2 实现网络连接........................................................................................................................... 341 8.5.3 实现聊天功能........................................................................................................................... 346 8.5.4 能够显示对方玩的状态........................................................................................................... 347 8.5.5 当一方消去一行时,对方随机增加一行 ............................................................................... 348 8.5.6 游戏开始、停止、暂停........................................................................................................... 350 8.5.7 一方结束时,使对方结束,并弹出游戏得分状况的对话框................................................ 351 8.5.8 在游戏关闭的时候,将所有网络资源释放 ........................................................................... 351 8.6 将游戏打包,发布我们的游戏........................................................................................................ 352 8.6.1 打包的好处............................................................................................................................... 352 8.6.2 如何打包................................................................................................................................... 352 8.7 Java代码风格和编写文档................................................................................................................. 356 8.7.1 Java的代码风格........................................................................................................................ 356 8.7.2 变量命名规则........................................................................................................................... 357 8.7.3 编写文档................................................................................................................................... 358 8.8 进一步实践 ....................................................................................................................................... 361 8.8.1 游戏还存在的问题................................................................................................................... 361 8.8.2 使游戏界面变得更漂亮........................................................................................................... 362 8.9 本章知识点回顾 ............................................................................................................................... 362 第 1 章 Java 基础 Java是一门发展很快的计算机语言,现在许多大型项目开始逐渐考虑使用Java来编写。 Java以其独特的可跨平台运行和开发速度快、维护方便等特性受到许多开发者的青睐。这 一章我们将要介绍一些Java的基础知识,从中读者可以了解到Java的历史、现状和前景,同 时也会了解到如何编写和运行一个简单的Java程序。 1.1 Java简介 Java是由Sun公司开发的新一代编程语言,使用它可在各种不同机器、不同操作平台的 网络环境中开发软件和使用软件。不论你使用的是哪一种网络浏览器,哪一种计算机,哪 一种操作系统,只要机器上已经安装了Java运行环境(Java Runtime Environment)或者系 统已经注明了“支持Java”,你就可以看到嵌有Java小应用程序(Applet)的生动活泼的网 页,你也可以运行别人在任何机器、任何操作系统上编写和编译的Java应用程序。Java正在 逐步成为Internet上主要的开发语言,也正在成为许多大型网络系统的首选开发语言。它彻 底改变了应用软件的开发模式,带来了自PC机面世以来的又一次技术革命,为迅速发展的 信息世界增添了新的活力。 1.1.1 Java的历史 Sun的Java语言开发小组成立于1991年,其目的是开拓消费类电子产品市场,例如,交 互式电视、烤面包机等。Sun内部人员把这个项目称为Green,那时World Wide Web还没有 发展呢!该小组的领导人James Gosling是一位非常杰出的程序员。他出生于1957年,于1984 年加盟Sun Microsystem公司,之前在一家IBM研究机构工作。他是Sun NeWs窗口系统的总 设计师,也是第一个用C实现的EMACS的文本编辑器COS MACS的开发者。 由于消费类电子产品追求的是可靠性、标准化、使用简单、费用低等特性,对采用什 么处理器不感兴趣。所以,迫切需要一种语言能够使所开发的系统与应用平台(例如:无 论是什么型号的交互式电视)无关,使得在一种平台上开发的控制系统能够很方便地移植 到各种类型的平台上。 为了实现系统与平台无关的目标,Gosling决定改写C编译器。但是,Gosling马上就发 现仅仅靠改写是无法满足需要的,于是在1991年6月决定自己开发一门新的语言。他为这门 语言起名为Oak,这就是Java语言的前身。因为Oak是Sun公司另一种语言的注册商标,所 以Java是后来才改的名。 Gosling在开始写Java时,不仅仅扩充了语言机制本身,更注重于语言所运行的软硬件 2 Java 游戏编程导学 环境。Gosling在设计中采用了虚机器码(Virtual Machine Code)方式,即Java语言编译后 产生的是虚机器码,虚机器码由Java虚拟机解释执行,Java虚拟机中有一个解释器。每一个 操作系统都可以创建一个Java虚拟机以解释执行Java的虚机器码。这样一来,Java就成了与 平台无关语言。 到了1994年,WWW已如火如荼地发展起来。Gosling意识到WWW需要一个中性的浏 览器,它不依赖于任何硬件平台和软件平台,它应是一种实时性较高、安全可靠、有交互 功能的浏览器。于是Gosling决定用Java开发一个新的Web浏览器,这就是Hot Java浏览器。 它虽然没有获得大的发展,但是却展示了Java可能带来的广阔市场前景。Hot Java在1995年 5月23日发布,在业界引起了巨大的轰动,Java的地位也随之得到肯定。又经过一年的试用 和改进,Java 1.0版终于在1996年初正式发布。 Hot Java浏览器的出现,也导致了几个主流浏览器开始支持Java小应用程序(Applet)。 现在,IE、NS都能够支持Java Applet,使得页面更加丰富多彩了。 1997年11月,国际标准化组织正式批准了Sun等公司提出的Java标准,Java标准化促进 了它的进一步发展,也标志着Java语言的成熟。 目前Java已经发展了多个版本,从1.02到1.1、1.2 到目前的1.5 版本。Java 1.2以后的版 本统称为Java 2。每次新版本发布,都会给Java注入新的生命力。 1.1.2 Java的特性 Java具有两大特性:可跨平台运行,面向对象。这两个特性是Java得以迅速发展的重要 原因。 跨平台运行机制 Java程序具有可跨平台运行的特性,这个特性取决于它的应用程序的运行机制。通常 计算机语言的运行机制如图1.1所示。 图 1.1 通常计算机语言的运行机制 而Java的运行机制则如图1.2所示。 源代码 编译器Pentium 可运行的Binary码 编译器PowerPC 编译器SPARC 可运行的Binary码 可运行的Binary码 第 1 章 Java基础 3 图 1.2 Java 运行机制 由图1.1、图1.2可以得知,普通的计算机编程语言大都是将源代码编译成机器码,对不 同的平台其机器码是不同的。由于不同平台的特性和应用程序接口(API)的不同,其源代 码往往也是不同的。这就造成了普通编程语言在移植上的困难。而Java引进的虚机器码的 概念解决了这个问题。因为所有的Java解释器都是按照同一个规则来解释执行Java虚机器码 的,所以所有的Java源代码最终生成的虚机器码对不同平台都是一样的。同时所有的虚机 器码都是运行在相同的Java虚拟机上,所以,Java对于不同的平台却可以有相同的源代码。 这就是Java可跨平台运行的特性。 对于运行于Internet上的网络程序,一个最大的要求是可以跨平台运行。这是因为网络 上会存在许多不同的机器、不同的操作系统。而Java的跨平台特性使之成为最理想的网络 编程语言。 面向对象 面向对象其实是现实世界模型的自然延伸。现实世界中任何实体都可以看作是对象。 对象之间通过信息相互作用。另外,现实世界中任何实体都可归属于某类事物,任何对象 都是某一类事物的实例。如果说传统的过程式编程语言是以过程为中心、以算法为驱动的 话,面向对象的编程语言则是以对象为中心、以信息为驱动。用公式表示,过程式编程语 言为:程序=算法+数据;而面向对象编程语言为:程序=对象+信息。 所有面向对象编程语言都支持3个概念:封装、多态性和继承,Java也不例外。Java提 供了类机制和接口。通过类和接口,我们就可以实现对方法和数据的封装,同时通过类的 继承以及继承时的多态性,我们实现了代码复用。Java程序是由一个一个的类组成,这决 定了Java是一种纯粹的面向对象的编程语言。Java的这个特性决定了使用Java语言开发产品 的高速度和产品的可维护性。 其他特性 Java还有一些特性,比如分布性、健壮性、安全性、支持多线程等等,这些特性都反 映了Java语言设计的精妙。同时,Java也是一门简单易学的语言,相信读者很快就会认识到 这一点。 源代码 不同平台下的编译器 虚机器码 不同平台下的解释器 4 Java 游戏编程导学 1.1.3 Java的应用 Applet Applet是嵌入到网页里用于装饰网页或者完成某种特殊功能的小应用程序。Applet由浏 览器中的Java解释器负责解释执行。 Application Java Application就是独立运行在Java虚拟机上的一系列的应用程序。 servlet servlet是运行在服务器端的小程序,它负责处理客户端传来的请求(request),然后传 给客户端一个响应(response)。 J2SE、J2EE 和 J2ME J2SE(Java 2 Standard Edition)就是我们印象中的普通的Java语言,这是一个标准的API 和工具包,是J2EE和J2ME的基础。 J2EE(Java 2 Enterprise Edition),顾名思义,它向企业级用户提供服务,使得企业可 以把自身的信息通过Internet的形式发布,也就是电子商务技术。同时可以用于解决电子政 务等一系列问题。 电子商务和信息技术的快速发展及对它的需求给应用程序开发人员带来了新的压力。 为了降低成本并加快企业应用程序的设计和开发,J2EE平台提供了一个基于组件的方法, 来设计、开发、装配及部署企业应用程序。J2EE平台提供了多层分布式应用模型、组件重 用、一致化的安全模型以及灵活的事务控制。 J2ME(Java 2 Micro Edition)类似于J2EE的一个平台。其实Java最早的目的就是满足 一些嵌入式装置的开发需要。在Java 1.0.2以前的几个版本,这项功能一度被忽略,但是在 1.0.2版本的时候进行了重新开发。当发展到Java 2的时候,Sun推出了一个专门的软件包 J2MEWDK,支持进行嵌入式开发。目前大家关注最多的是手机游戏的开发,但是J2ME能 做的远远不止这些。 如果读者对J2EE或者是J2ME有兴趣的话,请到http://java.sun.com/上寻找更多的信息。 1.1.4 J2SE 1.5的新特性 J2SE 1.5(开发代号Tiger)是Java平台和语言上的一个重要修改,目前主要包括了15 个JSR的请求和其他一些类似的更新。这次的Release主要关注于几个关键的主题:品质、 监视和管理、性能和可扩展性、轻松的开发以及桌面客户端。 轻松的开发(Ease of Development) 你可能已经听到过关于减轻开发难度而做的Java语言上的修改。这次J2SE根据JSR的要 求实现以下几个JSR:JSR 201 包含了4个修改,JSR 175的核心是支持元数据(metadata), 第 1 章 Java基础 5 而JSR 14则规范了泛型。元数据功能提供了声明式的开发,并且取代了一些工具的代码生 成和维护功能。泛型提升了无需手动转型(manual casting)的代码复用,通常manual casting 都会带来类型安全性上的一些问题。 另外的4个修改分别是: (1)用for循环来遍历容器(Collection 类型),而不需要显式的声明容器的迭代器 (Iterator)。 (2)枚举类型提供了超越类似final static int的、增强的类型安全性。 (3)在泛型中使用基本数据类型(primitive types)的时候提供自动装箱(autoboxing) 功能(原来的泛型中是不能使用基本类型的)。 (4)引入了静态常量(static constants)类,改进显式的共享一个静态数据。 为了实现轻松的开发,除了语言上的修改之外,还有一些额外的东西,比如一些怀念 printf函数的人会发现它又回来了;一个新的并发工具(在JSR 166中提及)将使得多线程编 程变得更加简单轻松。 可扩展性和性能(Scalability and Performance) J2SE 1.5版本承诺改进软件的可扩展性和性能,尤其是在启动时间和内存印记 (memory footprint)上,将使得用户能以最快的速度发布一个应用程序。从JSR 163上将实 现内建的性能工程(performance ergonomics)和一个功能强劲的API profile工具。 监视和管理(Monitoring and Manageability) 监视和管理是Tiger中的一个主要特性。那些在J2EE平台上使用JMX的开发者看到这样 的特性能在J2SE中实现将会非常开心。通过对JVM的监视,将允许对已发布的应用程序健 康性的完全检查,包括对底层内存泄漏检测,错误处理甚至是API 堆栈跟踪(stack trace) 的监视。 核心的 XML 支持(Core XML Support) J2SE 1.5的介绍被修改为XML的核心平台,表示Java的核心API将包括XML1.1、SAX 2.0 和DOM Level3。Web service方面的API、JAX-RPC和JAXB将继续出现在Web Service的包中, 在以后的新版本中这些API将被添加到核心API中去。 桌面客户端(Desktop Client) 最后一个重点的新特性是桌面客户端。这将带来几个内建的新的Look & Feels支持,并 且增强了对皮肤(skins)的支持。除了启动速度和内存印记的增强,桌面开发者又多了几 个值得期待的新特性。 对 Unicode 3.1 的支持(Unicode 3.1 Support) 32位的代理字符(surrogate character)支持将会很谨慎地添加到新的版本中,所以1.5 版本将仍然使用16位的char类型。 6 Java 游戏编程导学 新的 IO 支持(New IO Support) 新版本将提供对异步IO的支持,并且支持在平台中适当的地方开拓更深入的使用这些 API。 1.2 Java语言基本概念 前一节已经简要介绍了Java语言,现在就开始深入到Java语言内部,来介绍Java语言的 基本数据类型、控制语句等重要组成部分。学完这一节,我们就可以编写一个非常简单的 小程序。 1.2.1 基本数据类型 数据类型指明了变量和表达式的状态和行为。本节我们将讲述Java的简单数据类型。 常量与变量 (1)常量 Java有几种类型的常量,如整型常量345,浮点型常量33.2等,所有常量都用final做修 饰符。 下面是几个常量的定义: final int a=345; final float b=33.2; final double c=33.2d; final String d='ddddd'; (2)变量 变量是Java程序中的基本存储单元,它的定义包括变量名、变量类型和作用域。 变量名应该是一个合法的标识符,它允许包括字母、数字、下划线、$字符,不能以数 字开头,而且不能为保留字。 变量的声明格式为: type identifier [=value][,identifier[=value]…]; 多个变量之间用“,”分隔,结束用“;”。 下面是几个合法的变量声明: int a1,b2,c3; int a5=6,b9=8; float tr_$=33.; double sxf$; String _s44=’dddd’; 第 1 章 Java基础 7 下面是非法的变量声明: int 1a; //数字打头 float String=33.; //String是保留字 double aaa#; //#是特殊字符 String ddd-ddd=’dddd’; //-是特殊字符 变量的作用域可以分为:局部变量、类变量、方法参数、异常处理参数等等。局部变 量在方法或方法的一段代码中声明,它的作用域为它所在的代码块(整个方法或方法中的 某段代码)。类变量在类中声明,而不是在类的某个方法中声明,它的作用域为整个类。 方法参数传递给方法,它的作用域就是这个方法。异常处理参数传递给异常处理代码,它 的作用域就是异常处理部分。在一个确定的域中,变量名应该是惟一的。通常一个域可以 使用大括号{}来划定。 如下例在编译的时候将会由于重复对a定义而出错: int a=23; a=45; int a=67; 而如果加上域定界符{}就不会出错了: { int a=23; a=45; } int a=67; 整型数据 (1)整型常量 Java中的整型常量有3种表示方法: · 十进制整数,如24、-36、33。 · 八进制整数,以0开头,如0121表示十进制数81,-012表示十进制数-10。 · 十六进制整数,以0x或0X开头,如0x121表示十进制数290,-0X11表示十进制数-17。 整型常量在机器中占32位,具有int型的值。对于long型值,则要在数字后加L或l,如 123L表示一个长整数,它在机器中占64位。 (2)整型变量 Java的整型数据类型有4种:byte、short、int和long。这4种整数类型所占有的位数如表 1.1所示。 8 Java 游戏编程导学 表1.1 4种整数类型 类型 占有字节数 占有位数 byte 1 8 short 2 16 int 4 32 long 8 64 这4种类型都是有符号数,都可正可负。Java中没有无符号数,这减少了数据类型的复 杂度。 由于不同的机器对于多字节数据的存储方式不同,可能是从低字节向高字节存储,也 可能是从高字节向低字节存储,这样,在分析网络协议或文件格式时,为了解决不同机器 上的字节存储顺序问题,用byte类型来表示数据是合适的。而通常情况下,由于byte表示的 数据范围很小,容易造成溢出,应避免使用。 short类型则很少使用,它限制数据的存储为先高字节后低字节,这样在某些机器中会 出错。 下面是整型变量定义的例子: byte a=3; //指定变量a为byte型 short b=04; //指定变量b为short型 int c=0x5; //指定变量c为int型 long l=61; //指定变量l为long型 浮点型(实型)数据 (1)浮点型常量 · 十进制数形式,由数字和小数点组成,且必须有小数点,如0.123、.123、123.或123.0。 · 科学记数法形式,如1.23e3或123E3,其中e或E之前必须有数,且e或E后面的指数 必须为整数。 浮点型常量在机器中占64位,具有double型的值。对于float型的值,要在数字后加f或F, 如12.3F,它在机器中占32位,且表示精度较低。 (2)浮点型变量 实型变量的类型有float和double两种,表1.2列出了这两种类型所占有的位数。 表1.2 两种浮点类型 类型 所占字节数 所占位数 表示范围 float 4 32 4e-038~3.4e+038 double 8 64 1.7e-308~1.7e308 双精度类型double比单精度类型float具有更高的精度和更大的表示范围,常常使用。 下面是浮点型数据类型定义示例: 第 1 章 Java基础 9 float a=33.3f;//指定变量a为float型 double b=44.4;//指定变量b为double型 字符型数据 (1)字符型常量 字符型常量是用单引号括起来的一个字符,如'a'、'A'。 此外,Java提供的转义字符,以反斜杠(\)开头,将其后的字符转变为另外的含义, 下面列出了Java中的转义字符。Java中的字符型数据是16位无符号型数据,它表示Unicode 集,而不仅仅是ASCII集,例如\u0061表示ISO拉丁码的'a'。 转义字符描述如下: \ddd 1到3位8进制数据所表示的字符(ddd) \uxxxx 1到4位16进制数所表示的字符(xxxx) \' 单引号字符 \\ 反斜杠字符 \r 回车 \n 换行 \f 走纸换页 \t 横向跳格 \b 退格 (2)字符型变量 字符型变量的类型为char,它在机器中占16位,其范围为0~65535。 字符型变量的定义如: char c='a';//指定变量c为char型,且赋初值为'a' Java中的字符型数据不能用作整数,因为Java不提供无符号整数类型,但是同样可以把 它当作整数数据来操作。 例如: int a=3; char b='1'; char c=(char)(a+b);//c='4' 上例中,在计算加法时,字符型变量b被转化为整数,进行相加,最后把结果又转化为 字符型。 (3)字符串常量 Java的字符串常量是用双引号括起来的一串字符,如"Hello world!\n"。但不同的是,Java 中的字符串常量是作为String类的一个对象来处理,而不是一个数据。String类提供了很多 方便的对字符串操作的方法。 下例可以申请一个字符串常量: String str="Hello world!\n"; 10 Java 游戏编程导学 布尔型数据 布尔型数据有两个值:true和false,且它们不对应于任何整数值,在流控制中常用到布 尔型数据。 布尔型变量的定义如: boolean b=false;//定义b为布尔型变量,且初值为false 各类数值型数据间的混合运算 (1)运算过程中自动类型转换 整型、实型、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型, 然后进行运算。转换从低级到高级,转换规则为: (byte或short) op int→int (byte或short或int) op long→long (byte或short或int或long) op float→float (byte或short或int或long或float) op double→double char op int→int 其中,箭头左边表示参与运算的数据类型,op为运算符(如加、减、乘、除等),右 边表示转换后进行运算的数据类型。 下面举两个例子。 例1: int a=10; float b=0.8; double c=3.0; int d=a+b+c; 则d=? 答:d=13。 例2: float a=0.8; int b=a; float c=b*a; 则c=? 答:c=0。因为第二句的执行结果为b=0。 (2)强制类型转换 高级数据要转换成低级数据,需用到强制类型转换,如: int a; byte b=(byte)a;//把int型变量a强制转换为byte型 这种使用可能会导致溢出或精度的下降,最好不要使用。 第 1 章 Java基础 11 示例如下: float a=0.8; float b=3.0; int c=2; int d=(int)(a*b)/c; 则d=? 答:d=1。在int d=(int)(a*b)/c这一句代码中,a*b得到的是float类型的结果,为2.4,然 后进行强制转换,得到2,然后除以2,就会得到1这个结果。 1.2.2 数组 数组是有序数据的集合,数组中的每个元素具有相同的数据类型,数组名和下标可惟 一地确定数组中的元素。数组分为一维数组和多维数组,下面分别进行介绍。 一维数组 (1)一维数组的定义 一维数组的定义方式为: type arrayName[]; 其中,类型(type)可以为Java中任意的数据类型,包括简单类型、组合类型,数组名 arrayName为一个合法的标识符,[]指明该变量是一个数组类型变量。 例如: int intArray[]; 声明了一个整型数组,数组中的每个元素均为整型数据。Java在数组的定义中并不为数组 元素分配内存,因此[]中不用指出数组长度,而且对于如上定义的一个数组是不能访问它 的任何元素的。我们必须为它分配内存空间,这时要用到运算符new,其格式如下: arrayName=new type[arraySize]; 其中,arraySize指明数组的长度。如: intArray=new int[3]; 为一个整型数组分配3个int型整数所占据的内存空间。 通常,这两部分可以合在一起,格式如下: type arrayName=new type[arraySize]; 示例: int intArray[]=new int[3]; 对数组元素可以逐个进行赋值,也可以在定义数组的同时进行初始化。 例如: 12 Java 游戏编程导学 int a[]={1,2,3,4,5}; 用逗号(,)分隔数组的各个元素,系统自动为数组分配空间。 (2)一维数组元素的引用 定义了一个数组,并用运算符new为它分配了内存空间后,就可以引用数组中的每一 个元素了。数组元素的引用方式为: arrayName[index] 其中,index为数组下标,它可以为整型常数或表达式。如a[3]、b[i](i为整型)、c[6*I] 等。下标从0开始,一直到数组的长度减1。对于上面例子中的intArray数组来说,它有3个 元素,分别为intArray[0]、intArray[1]、intArray[2]。注意:没有intArray[3]。当强行访问 intArray[3]的时候,就会抛出数组越界的异常。 数组都有一个属性length指明它的长度,例如:intArray.length指明数组intArray的长度。 多维数组 Java中多维数组被看作数组的数组。例如二维数组为一个特殊的一维数组,其每个元 素又是一个一维数组。下面主要以二维数组为例来进行说明。 (1)二维数组的定义 二维数组的定义方式为: type arrayName[][]; 例如: int intArray[][]; 与一维数组一样,这时对数组元素也没有分配内存空间,同样要使用运算符new来分 配内存,然后才可以访问每个元素。 对多维数组来说,分配内存空间有下面几种方法: · 直接为每一维分配空间,如: int a[][]=new int[2][3]; · 从最高维开始,分别为每一维分配空间,如: int a[][]=new int[2][]; a[0]=new int[3]; a[1]=new int[3]; · 在定义数组的时候进行初始化,如: int a[][]={{1,2},{3,4}}; (2)二维数组元素的引用 对二维数组中的每个元素,引用方式为:arrayName[index1][index2],其中index1、index2 第 1 章 Java基础 13 为下标,可为整型常数或表达式,如a[2][3]等。同样,每一维的下标都从0开始。 1.2.3 运算符和表达式 运算符指明对运算数所进行的运算。按运算数的数目可分为一元运算符(如++,--)、 二元运算符(如+、>)和三元运算符(如?:)。对于一元运算符来说,可以有前缀表达式 (如++i)和后缀表达式(i++)。中缀表达式为a+b。按照运算符功能来分,基本的运算符 有下面几类: (1)算术运算符(+,-,*,/,%,++,--) (2)关系运算符(>,<,>=,<=,==,!=) (3)布尔逻辑运算符(!,&&,||) (4)位运算符(>>,<<,>>>,&,|,^,~) (5)赋值运算符(=,及其扩展赋值运算符如+=) (6)条件运算符(?:) (7)其他(包括分量运算符·,下标运算符[],实例运算符instanceof,内存分配运算符 new,强制类型转换运算符(类型),方法调用运算符()等) 下面主要讲述前6类运算符。 算术运算符 算术运算符作用于整型或浮点型数据,完成算术运算。 (1)二元算术运算符(见表1.3) 表1.3 二元算术运算符 运算符 用法 描述 + op1+op2 加 - op1-op2 减 * op1*op2 乘 / op1/op2 除 % op1%op2 取模(求余) Java对加运算符进行了扩展,使它能够进行字符串的连接,如"abcde"+"fgh",得到字 符串"abcdefgh"。 对取余运算符%来说,其运算数可以为浮点数,37.2%10=7.2。 (2)一元算术运算符(见表1.4) 表1.4 一元算术运算符 运算符 用法 描述 + +op 正 ++ ++op或op++ 加1 14 Java 游戏编程导学 (续表) 运算符 用法 描述 - -op 负 -- --op或op-- 减1 i++与++i,i--与--i是有区别的,i++和i--表示先使用i而后进行加1或减1,而++i和--i 表示先进行加1或减1然后再取得i的值。 如下例: int a=3,b=3,c=3,d=3; int dest1=a++; int dest2=++b; int dest3=c--; int dest4=--c; 其最后结果为: dest1=3;a=4; dest2=4;b=4; dest3=3;c=2; dest4=2;c=2; 关系运算符 关系运算符用来比较两个值,返回布尔类型的值true或false。 关系运算符都是二元运算符,如表1.5所示。 表1.5 关系运算符 运算符 用法 返回true的时候 > op1>op2 op1大于op2 >= op1>=op2 op1大于或等于op2 < op1
2; 则a为true。 布尔逻辑运算符 布尔逻辑运算符进行布尔逻辑运算,包括&&、||、!3个运算符。前两个是二元运算符, 第 1 章 Java基础 15 后一个是一元运算符。 &&:逻辑与,当两者都为真的时候,结果才为真。 ||:逻辑或,当两者中有一个为真或者都为真的时候,结果为真。 !:逻辑否。 对于布尔逻辑运算,先求出运算符左边的表达式的值。对逻辑或运算,如果左边的表 达式为true,则直接返回结果为true。对逻辑与运算,如果左边的表达式为false,则直接返 回结果为fasle。 布尔逻辑运算的规则如表1.6所示。 表1.6 布尔逻辑运算规则 op1 op2 op1&&op2 op1||op2 !op1 true true true true false true false false true false false true false true true false false false false true 下面的例子说明了关系运算符和布尔逻辑运算符的混合使用。 boolean a=true; boolean b=a&&3<2; boolean c=a||b; boolean d=!b; 结果为: a=true,b=false,c=true,d=true 位运算符 位运算符用来对二进制位进行操作,Java中提供了如表1.7所示的位运算符。 表1.7 位运算符 运算符 用法 描述 ~ ~op 按位取反 & op1&op2 按位与 | op1|op2 按位或 ^ op1^op2 按位异或 >> op1>>op2 op1右移op2位 << op1<>> op1>>>op2 op1无符号右移op2位 位运算符中,除~以外,其余均为二元运算符,运算数只能为整型和字符型数据。 Java使用补码来表示二进制数,在补码表示中,最高位为符号位,正数的符号位为0, 负数为1。补码的规定如下: 16 Java 游戏编程导学 · 对正数来说,最高位为0,其余各位代表数值本身(以二进制表示),如+42的补码 为00101010。 · 对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。 如-42的补码为11010110(00101010按位取反后加1,即11010101+1=11010110)。 · 用补码来表示数,0的补码是惟一的,都为00000000(而在原码、反码表示中,+0 和-0的表示是不惟一的,可参见相关书籍),而且可以用111111表示-1的补码(这 也是补码与原码和反码的区别)。 赋值运算符 赋值运算符=把一个数据赋给一个变量,在赋值运算符两侧的数据类型不一致的情况 下,如果左侧变量的数据类型的级别高,则右侧的数据会转化成与左侧相同的数据类型, 然后赋给左侧变量;否则,需要使用强制类型转换运算符,例如: byte a=100;//自动转换 int b=a; int c=100;//强制类型转换 byte d=(byte)c; 在赋值运算符=之前加上其他运算符,即构成扩展赋值运算符,例如,a+=10等价于 a=a+10。也就是对于如下赋值表达式: var=var op expression 用扩展赋值运算符可表达为: var op=expression 条件运算符 条件运算符?和:为三元运算符,它的一般形式为: 表达式?语句1:语句2 其中表达式语句的值应为一个布尔值,如果这个布尔值为ture,则执行语句1,否则执 行语句2,而且语句1和语句2需要返回相同的数据类型,且该类型不能为void。 例如: int a=(3>2)?3:2; 则执行结果为: a=3; 这个语句可以用if-else语句来表示。 表达式与运算符的优先级 对一个表达式进行运算的时候,要按照运算符的优先顺序从高向低进行,同级的运算 规则按照从左到右的方向进行。 第 1 章 Java基础 17 Java中运算符的优先级由高到低排列如下: [] () ++ -- !~ instanceof new(type) * / % + - >> >>> << <> <= >= == != & ^ | && || ?: = += -= *= /+ %= ^= &= |= <<= >>= >>>= 一般来说,我们不需要搞清楚这个复杂的优先级顺序,在编写程序的时候,只要尽量 多使用()来界定表达式计算的顺序就行。 1.2.4 基本控制语句 Java程序通过流控制来执行程序语句,完成一定的功能。语句可以是单一的一条语句 (如c=a+b;),也可以是复合语句。 下面分别介绍Java中的流控制语句,包括: · 分支语句 if-else,break,switch,return · 循环语句 while,do-while,for,continue · 异常处理语句 try-catch-finally,throw 最后我们简单介绍一下注释语句。 分支语句 分支语句提供了一种控制机制,使得程序的执行可以跳过这些语句(不执行这些语句), 而转去执行特定的语句。 (1)条件语句if-else if-else语句根据判定条件的真假来执行两种操作中的一种,它的格式为: if(布尔表达式) 语句1; 18 Java 游戏编程导学 else 语句2; 简要说明如下: · 布尔表达式是任意一个返回布尔型数据的表达式。 · 每个单一的语句后都必须有分号。 · 语句1、语句2可以为复合语句,这时要用大括号{}括起来,建议对单一的语句也用 大括号括起,这样程序的可读性强,而且有利于程序的扩充(可以在其中填加新的 语句)。{}外面不加分号。 · else子句是任选的。 · 若布尔表达式的值为true,则程序执行语句1,否则执行语句2。 if-else语句的一种特殊形式为: if(表达式1) { 语句1 } else if(表达式2) { 语句2 } … else if(表达式M) { 语句M } else { 语句N } else子句不能单独作为语句使用,它必须和if 配对使用。else总是与离它最近的if 配对。 可以通过使用大括号{}来改变配对关系。 举例:比较两个数的大小。 int a=10; int b=20; String str=""; if(a>b) str="a>b"; else str="ab" 举例:判断一个数是不是既能被4整除又能被3整除。 第 1 章 Java基础 19 int a=24; String str=""; if(a%4==0) { if(a%3==0) str="a能被4和3整除"; else str="a能被4但不能被3整除"; } else { if(a%3==0) str="a能被3但不能被4整除"; else str="a不能被4整除,也不能被3整除"; } 运行结果为: str为"a能被4和3整除" (2)多分支语句switch switch语句根据表达式的值来执行多个操作中的一个,它的一般格式如下: switch(表达式) { case 值1: 语句1; break; case 值2: 语句2; break; … case 值N: 语句N; break; default: defaultStatement; } 简要说明如下: · 表达式可以返回任一简单类型的值(如整型、实型、字符型),多分支语句把表达 式返回的值与每个case子句中的值相比。如果匹配成功,则执行该case子句后的语 句序列。 · break语句用来在执行完一个case分支后,使程序跳出switch语句,即终止switch语 句的执行。因为case子句只是起到一个标号的作用,用来查找匹配的入口,从此处 开始执行,对后面的case子句不再进行匹配,而是直接执行其后的语句序列,因此 在每个case分支后,要用break来终止后面的case分支语句的执行。在一些特殊情况 20 Java 游戏编程导学 下,多个不同的case值要执行一组相同的操作,这时可以不用break。case分支中包 括多个执行语句时,可以不用大括号{}括起。 · default子句是任选的。当表达式的值与任一case子句中的值都不匹配时,程序执行 default后面的语句。如果表达式的值与任一case子句中的值都不匹配且没有default 子句,则程序不执行任何操作,而是直接跳出switch语句。 · case子句中的值必须是常量,而且所有case子句中的值是不同的。 · switch语句的功能可以用if-else来实现,但在某些情况下,使用switch语句更简练, 可读性更强,而且程序的执行效率更高。 举例: int a=100; switch(a) { case 100: case 10: str="a等于10或者100"; break; default: str="a不等于10或者100"; } 运行结果为: str为"a等于10或者100"; 从该例中我们可以看到break语句的作用。 (3)return语句 return语句是从当前方法中退出,返回到调用该方法的语句处,并从紧跟着该语句的下 一条语句继续程序的执行。 return语句有两种格式,第一种为: 返回表达式 返回一个值给调用该方法的语句,返回值的数据类型必须和方法声明中的返回值类型 一致。可以使用强制类型转换来使类型一致。 第二种形式为: 返回值; 当一个方法的返回值为void的时候,使用这种形式,它不返回任何值。 return语句可以用在方法中的任何地方,但是一旦执行了return语句,就会从方法中跳 出去,后面的语句就不会再执行了。 示例如下: int returnBig(int a,int b) 第 1 章 Java基础 21 ( if(a>b) 返回值 a; else 返回值 b; } 这个方法返回a与b中较大的那个数值。 循环语句 循环语句的作用就是反复执行一段代码,直到满足终止循环的条件为止,一个循环一 般应包括4部分内容: · 初始化部分(initialization) 用来设置循环的一些初始条件,如设置计数器为0。 · 循环体部分(body) 这是反复循环的一段代码,可以是单行代码,也可以是多行 代码,但是必须用大括号括起来。 · 循环中用于改变计数器的部分(iteration) 这是用来控制计数器,从而控制循环 次数的语句。 · 终止部分(termination) 这是一个逻辑表达式,每一次循环都要对该表达式求值, 以验证是否满足循环终止条件。 Java中提供的循环语句有:for语句、while语句和do-while语句。下面分别加以介绍。 (1)for语句 for语句的一般形式为: for(初始化;终止条件;增量) { 循环体; } 下面对这个语句简要的说明一下: · for语句执行时,首先执行初始化操作,然后判断终止条件是否满足,如果满足, 则执行循环体中的语句,最后执行增量部分。完成一次循环后,重新判断终止条件。 · 可以在for语句的初始化部分声明一个变量,它的作用域为这个for语句。 · for语句通常用来执行循环次数确定的情况(如对数组元素执行操作),也可以根 据循环结束条件执行循环次数不确定的情况。 · 在初始化部分和增量部分可以使用逗号来进行多个操作。例如: for(i=0,j=10;i<j;i++,j--=) { … } · 初始化、终止以及增量部分都可以为空语句(但分号不能丢掉),三者均为空的时 候,相当于一个无限循环。 22 Java 游戏编程导学 举例: int sum=0; for(int i=0;i<10;i++) { sum+=i; } 执行结果为: i=55 (2)while语句 while语句的一般格式为: [初始化] while(终止条件) { 循环体; [增量;] } 简要说明如下: · 当布尔表达式(termination)的值为true时,循环执行大括号中的语句。 · while语句首先计算终止条件,当条件满足时,才去执行循环中的语句。 举例: int i=0; int sum=0; while(i<=10) { sum+=i; i++; } 执行结果为: sum=55,i=10 (3)do-while语句 do-while语句实现“直到型”循环,它的一般格式为: [初始化] do { 循环体; [增量;] }while(终止条件); 第 1 章 Java基础 23 简要说明如下: · do-while语句首先执行循环体,然后计算终止条件,若结果为true,则循环执行大括 号中的语句,直到布尔表达式的结果为false。 · 与while语句不同的是,do-while语句的循环体至少执行一次。 举例: int sum=0; int i=0; do { sum+=i; i++; }while(i<=10) 执行结果为: sum=55,i=11。 (4)continue语句 continue语句用来结束本次循环,跳过循环体中下面尚未执行的语句,接着进行终止条 件的判断,以决定是否继续循环。它的格式为: continue; continue语句也可以用作跳转到括号指明的外层循环中,这时的格式为: continue outerLable; 例如: outer: for(int i=0;i<10;i++= { 外层循环 for(int j=0;j<10;j++= { 内层循环 if(j>i) { … continue outer; } … } … } 该例中,当满足j>i的条件时,程序执行完相应的语句后跳转到外层循环,执行外层循 24 Java 游戏编程导学 环i++,然后开始下一次循环。 举例: int i=0,sum=0; for(int i=0;i<100;i++) { if(i>10) continue; sum+=i; } 执行结果为: sum=55 异常处理语句 异常处理语句包括try…catch…以及throw语句。这些语句都是Java特有的。 try…catch…语句的格式为: try { … } catch(SomeExceptionvar) { //to do something to handle the exception } throw语句的格式为: void someFunction throw someException { … } 注释语句 Java可以采用的注释与C++类似,主要有以下3种: · //用于单行注释。 · /*…*/用于多行注释。注释从/*开始,到*/结束。 · /**…*/是Java所特有的doc注释。注释从/**开始,到*/结束。在JDK中有javadoc的 工具,通过这个工具可以由这些注释生成HTML形式的帮助文件。详见最后一章的 说明。 第 1 章 Java基础 25 1.3 编写和运行Java程序 本节我们来熟悉一下Java程序的开发环境,通过编写、编译、运行一个小程序,来了 解Java程序的编写和运行过程。 1.3.1 Java开发工具简介 JDK Java最基本的开发工具就是JDK(Java Development Kit),这 是 Sun公司发布的最权威、 最基本的开发工具包。任何人都可以从Sun的网站上免费得到JDK。 目前JDK存在着多个版本,从1.02到1.1、1.2到目前的1.4版本。每次新版本发布,都会 给Java注入新的生命力。 JDK软件包是基于文本的一个开发包。这个开发包中提供了几个非常重要的工具: · javac 可以将Java源代码编译生成class文件(Java的执行字节码)。 · java 用来执行class文件。 此外还有javadoc、javah、javap等重要的工具。关于这些工具的使用可以参看JDK附带 的文档,其中有非常详细的说明。 常用的 Java 集成开发环境 几乎所有的Java集成开发环境都是基于JDK的。要想使这些开发环境正常工作,必须先 安装JDK(有些集成环境在安装的时候,会自动给用户安装JDK)。下面介绍现在最常见 的Java集成开发环境。 (1)JBuilder 这是Barland Inprise公司推出的一个工具包,是与Braland Inprise公司推出的Delphi、 C++Builder配套的开发工具。 JBuilder是笔者最喜欢使用的一个集成开发环境,它的可视化设计做得不错,对Java各 方面的支持非常友好,而且它使用的几乎都是标准类库里的类,所以用它开发的程序,不 存在移植上的困难。目前Jbuider 9.0版之后的最新版已经发布。 (2)Visual Age for Java 这是IBM开发的一个Java集成开发工具。笔者没有用过,只是在IBM工作的时候看到同 事们用过,据说不错。 (3)JCreator 这是一个小巧玲珑的工具,用起来非常方便,它与JDK联系得特别紧密,读者可以到 www.jcreator.com网站去获得这个软件的最新版本。 26 Java 游戏编程导学 (4)Visual J++ 这是Microsoft公司的MSDEV系列开发工具中的一个,与普遍使用的开发工具Visual C++有相同的前端编辑和编译环境。但是,由于它过多地使用了它自己开发的与平台有关 的类,所以,使用Visual J++开发的东西在移植到非Windows系列操作系统上的时候就会出 现问题。建议读者不要使用这个开发环境。 (5)Eclipse 这是由Eclipse组织(网址为http://www.eclipse.org)开发的一个开源的集成编译环境。 更确切地说,它是一个平台,支持任何符合插件规范的软件在这个平台上运行。Eclispe和 Visual Age for Java是一脉相承的,这样说不仅仅是由于Eclipse组织得到IBM的大力支持, 更是因为Eclipse的开发小组原本是IBM公司开发Visual Age for Java的人员。由于它的开放 性和一贯提倡的敏捷开发原则,这个工具深受程序员的青睐。这个工具也是笔者目前使用 最多的工具,现在的最新版本是2.1.3,还有一个里程碑版本3.0M9。读者有兴趣的话,可以 去Eclispe的官方网址下载使用。 1.3.2 Hello World 我们接下来编写一个简单的Hello World程序,这个程序在控制台上打印出“Hello World!”的字样。 要新建一个文件,在文件里键入如下代码: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello world! "); } } 把这个文件存成HelloWorld.java。 在以上代码里,我们在第一行中新建了一个类。关于类的知识,将在下一章中详细讲 解。类中的main方法是程序在运行时执行的主方法。 System.out.println()是用来在控制台打印一个字符串的方法。 1.3.3 编译和运行 我们在此使用JDK来编译并运行上面编写的程序。 在文件所在的目录键入javac HelloWorld.java,如图1.3所示。 第 1 章 Java基础 27 图 1.3 运行 javac 进行编译 运行javac之后就会生成一个HelloWorld.class文件。这个文件就是Java的可执行文件, 我们可以使用java HelloWorld来执行它。执行结果如图1.4所示。 图 1.4 Hello World 程序的运行结果 1.4 本章知识点回顾 Java的应用 Applet:Applet是嵌入到网页中用于装饰网页或者完成某种特殊功能的小应 用程序。Applet由浏览器中的Java解释器负责解释执行 Application:Java Application就是独立运行在Java虚拟机上的一系列应用程序 servlet:servlet是运行在服务器端的小程序,它负责处理客户端传来的请求, 然后传给客户端一个响应 J2EE,J2ME 28 Java 游戏编程导学 (续表) 基本数据类型 整型、浮点型、字符型、布尔型 整型数据 byte,int,short,long 浮点型(实型)数据 float,double 字符常量 char 转义字符 \ddd 1 到3位八进制数据所表示的字符(ddd) \uxxxx 1 到4位十六进制数所表示的字符(xxxx) \' 单引号字符 \\ 反斜杠字符 \r 回车 \n 换行 \f 走纸换页 \t 横向跳格 \b 退格 布尔型数据 Boolean 只有两种取值:true或false 一维数组的定义方式为: type arrayName[]; 一维数组 一维数组元素的引用方式为: arrayName[index] 其中index为数组下标,它可以为整型常数或表达式。如a[3]、b[i](i为整型)、 c[6*I]等。下标从0开始,一直到数组的长度减1 多维数组 二维数组的定义方式为: ype arrayName[][]; 对二维数组中每个元素,引用方式为: arrayName[index1][index2] 其中,index1、index2为下标,可为整型常数或表达式,如a[2][3]等。同样, 每一维的下标都从0开始 算术运算符 二元算术运算符+,-,*,/,% 一元算术运算符+,-,++,-- 关系运算符 >,>=,<,<=,==,!= 布尔逻辑运算符 布尔逻辑运算符进行布尔逻辑运算,包括&&,||,!三个运算符。前两个是二元 运算符,后一个是一元运算符 位运算符 ~,&,|,^,>>,<<,>>> 赋值运算符 =,+=,-=,*=,/= 条件运算符 条件运算符?:为三元运算符,它的一般形式为: 表达式?语句1: 语句2 第 1 章 Java基础 29 (续表) []() ++ -- ! ~ instanceof Java中运算符的优先次 序(从上到下优先级逐渐 下降) new(type) * / % + - >> >>> << <> <= >= == != & ^ | && || ?: = += -= *= /+ %= ^= &= |= <<= >>= >>>= 条件语句:if-else if-else语句根据判定条件的真假来执行两种操作中的一种,它的格式为: if(布尔表达式) 语句1; else 语句2; 分支语句 多分支语句switch switch语句根据表达式的值来执行多个操作中的一个,它的一般格式如下: switch(表达式) { case 值1: 语句1; break; case 值2: 语句2; break; … case 值N: 语句N; break; [default: defaultStatement;] } 30 Java 游戏编程导学 (续表) return语句 return语句是从当前方法中退出,返回到调用该方法的语句处,并从紧跟着该 语句的下一条语句继续执行程序 返回语句有两种格式,第一种为: 返回表达式 返回一个值给调用该方法的语句,返回值的数据类型必须和方法声明中的返 回值类型一致。可以使用强制类型转换来使类型一致 第二种形式为: 返回值; 当一个方法的返回值为void的时候,使用这种形式,它不返回任何值 for语句的一般形式为: for(初始化;终止条件;增量) { 循环体; } while语句的一般格式为: [初始化] while(终止条件) { 循环体; [增量;] } do-while语句实现“直到型”循环,它的一般格式为: [初始化] do { 循环体; [增量;] }while(终止条件); 循环语句 continue语句用来结束本次循环,跳过循环体中下面尚未执行的语句,接着进 行终止条件的判断,以决定是否继续循环。它的格式为: continue; continue语句也可以用作跳转到括号指明的外层循环中,这时的格式为: continue outerLable; 第 1 章 Java基础 31 (续表) try…catch…语句的格式为: try { … } catch(Some Exception var) { …//to do something to handle the exception } 异常处理语句 throw语句的格式为: void someFunction throw someException { … } 注释语句 Java可以采用的注释与C++类似,主要有以下3种: //,用于单行注释 /*…*/,用于多行注释。注释从/*开始,到*/结束 /**…*/,这是Java所特有的doc注释。它从/**开始,到*/结束 第 2 章 面向对象编程起步 上一章简单介绍了Java语言,本章先来讲解Java面向对象编程的一些基本概念,然后通 过“幸运52”模拟游戏的编写,让读者对Java面向对象编程有更深的理解。 2.1 类 和 对 象 本节开始讲解Java的类以及对象,这些概念是面向对象编程的最基本的概念。要想学 会Java,必须要弄明白Java的类和对象。 2.1.1 类 类是组成Java程序的基本要素。通过使用类,可以把一个东西包装起来,提供给用户 一些有用的方法、变量和常量,而将其内部实现的细节隐藏。这样的封装有利于代码的复 用和改写,我们可以很方便地修改类中方法实现的细节,而不改变这个类的使用;同时可 以降低程序的模块之间的耦合程度,使得程序的修改升级变得更加容易。 类的声明 类是通过class关键字来声明的,格式如下: class myClass { //类名 class-body //类的主体 } 在第1行声明类的名字,在类体中声明类的成员变量和成员方法。在下面我们声明了一 个房子类,这个类抽象出了房子的一些性质,代码如下: class House{//房子类的类名 //成员变量 Window theWindow; boolean windowOpen; //构造函数 public void House(){ } public void House(Window window){ theWindow = window; windowOpen = false; } //成员函数 public void openWindow(){ 第 2 章 面向对象编程起步 33 windowOpen=true; } public void closeWindow(){ windowOpen=false; } public void printStatus(){ if(windowOpen){ System.out.println("窗口已经开了"); }else{ System.out.println("窗口已经关了"); } } } 在声明类的时候可以使用public和private来修饰。这些修饰词用来表示类在包外的访问 权限,相关内容将在2.3节中详细讲解。 成员变量 成员变量通常也称为属性。成员变量声明的格式为: type varName; 成员变量的类型可以是任何类型,包括简单类型、数组、类和接口。在一个类中,成 员变量的名字是惟一的,但是成员变量的名字可以和方法的名字相同。 在声明成员变量的时候,一般要使用public、private和protected等关键词,这些关键词 用来指明这个成员变量在类外的访问权限,如果不加以声明,Java默认声明为private。相 关 内容将在2.2.2节中详细讲解。 函数/方法 函数通常也称为方法。函数的声明格式为: return_type method_name(para_type paraname,[……, para_type paraname]){ //method body } 函数的名字可以为任意名字。它通常用来表述类所代表的事物可以完成的动作。以房 子为例,房子的窗户应该是可以开和关的,于是相应地具有动作openWindow()和 closeWindow()。 每个方法前也可以有public、private和protected关键字,用来指明这个方法在类外的访 问权限,相关内容将在2.2.2节中详细讲解。 构造函数 构造函数是一种特殊的函数,通常也称为构造子。构造函数的名字必须与它所在的类 完全相同,它表示类在初始化的时候应该完成的工作。构造函数的定义格式如下: class_name(para_type pare_name){ //method body 34 Java 游戏编程导学 } 在我们的例子中有两个构造函数public void House()和public void House(Window window),这两个函数完全同名而引数不同,这种函数名相同而引数不同的技术叫做重载, 我们将在后面进行介绍。 每一个类都应该有一个构造函数。一个类如果没有定义构造方法,则编译的时候自动 采用默认的构造方法,构造方法为不执行任何操作。如果这个类是继承得来的类,则采用 父类的构造方法。 2.1.2 对象 对象是由类生成的实例,如下方式可以生成一个类的实例: House hs=new House(); House是一个表示“屋子”的类,它抽象出了屋子的性质,而hs表示一个具体的屋子。 生成了一个对象之后,我们就可以通过它来调用对象的成员变量和方法。通过点运算符(.) 可以实现对变量的访问和方法的调用。 下面我们再写两个类,来简单运行一下这个小程序。House类中有一个类型为Window 类的成员变量,我们先给出Window类的代码,这里仅仅是举例说明,所以Window类什么 也不做。 public class Window(){ } 在下面的Manager类中我们来使用House类的对象。 public class Manager { public static void main(String[] args) { House hs=new House(); hs.closeWindow(); hs.printStatus(); hs.openWindow(); hs.printStatus(); } } 运行结果如图2.1所示。 Java运行时自动通过垃圾回收的方式周期性地释放无用对象所占用的内存,完成对象 的清除。当不存在对一个对象的引用时,该对象就会成为一个无用对象。这时,垃圾回收 机制就会把它当作一个垃圾,在回收的时候就会把它的内存清除。这样,我们就不需要去 跟踪每一个生成的对象,不必担心内存中有过多的垃圾,这是Java的一大优点。 第 2 章 面向对象编程起步 35 图 2.1 运行结果 2.1.3 一个小问题——static 细心的读者可能已经发现,在2.1.2节的例子中有这样一个声明: public static void main(String[] args) 这个main()函数的声明语句中,比我们过去见过的函数声明多加了一个关键字static, 这个关键字有什么用处呢?下面我们就来解释。 通常,我们创建类时会指出那个类的对象的外观与行为。除非用new 创建那个类的一 个对象,否则实际上并未得到任何东西。只有执行了new 后,才会正式生成数据存储空间, 并可使用相应的方法,除了两种特殊的情况。 一种情况是只想用一个存储区域来保存一个特定的数据——无论要创建多少个对象, 甚至根本不创建对象。另一种情况是需要一个特殊的方法,它没有与这个类的任何对象关 联。也就是说,即使没有创建对象,也需要一个能调用的方法。为满足这两方面的要求, Java中设立了static(静态)关键字。一旦将什么东西设为static,数据或方法就不会同那个 类的任何对象实例联系到一起。所以尽管从未创建那个类的一个对象,仍能调用一个static 方法,或访问一些static 数据。 在2.1.2节的例子中,main()函数声明为static,所以我们就可以用如下格式调用main() 函数而不用产生这个类的对象: Manager.Main() 注意:在这里我们只是用这个例子来说明静态成员的调用。一般情况下不可 能出现上面例子中的语句,因为Main()函数是由编译器自行调用的。 0 36 Java 游戏编程导学 2.2 类的继承和多态 2.2.1 Java的继承 Java语言中,继承是一个很重要的概念。通过继承可以实现代码的复用。一个类继承 另一个类,则这两个类就是父类与子类的关系。子类可以拥有父类的特征,同时还可以拥 有自己的特征。通过继承可以创建一个类的子类,其格式如下: public class sonClass extends fatherClass{ } 这样声明,表明sonClass是fatherClass的子类。如果一个类没有显式的声明extends,那 么它就是从基本类java.lang.Object中继承出来的。在Java中,所有的类都是从java.lang.Object 类继承出来的。 子类可以访问父类中通过public、protected关键词修饰的方法和成员变量。如果一个方 法和成员变量在父类中没有用任何关键词修饰,它就是friendly成员,也能够被这个类的子 类访问。而用private修饰的方法和成员变量是不能够被子类所访问的。 我们先声明一个类: public class Animal{ public final int MALE=1; public final int FEMALE=2; private int gender; protected Color color; public House()//构造方法{ } public void setGender(int g){ gender=g; } public int getGender(){ return gender; } public void printStatus(){ if(gender==MALE) System.out.println("Its gender is male"); else if(gender==FEMALE) System.out.println("Its gender is female"); } } 我们可以在子类中重载父类中已经定义了的方法,来给自己定义的子类增加一些新的 第 2 章 面向对象编程起步 37 特性。 我们在子类中定义一个和父类完全相同的方法,那么当这个子类的对象调用这个方法 的时候,它调用的是子类新定义的方法,而不是父类的方法。 如下例,我们定义子类: public class Dog extends Animal { public void printStatus() { if(gender==MALE) System.out.println("The dog's gender is male"); else if(gender==FEMALE) System.out.println("The dog's gender is female"); } } 那么当我们在其他类中这样调用时: Dog myDog=new Dog(); myDog.setGender(myDog.MALE); myDog.printStatus(); 运行结果为: The dog's gender is male 我们调用的setGender()方法仍然是在父类中定义的方法,而printStatus()方法却是我们 重新定义的方法。 super 关键字 如果我们重载了父类中的一个方法,但是仍然想调用父类中的方法,则可以使用super 关键字。 · super() 调用父类中的构造方法。 · super.methodName(paraType paraName) 调用父类中的methodName()方法。 如下例所示: public class Dog extends Animal{ protected boolean canBark; public Dog(){ super(); canBark=true; } public void printStatus(){ System.out.println("This is a dog"); super.printStatus(); } } 38 Java 游戏编程导学 那么在其他类中可用如下代码来调用: Dog myDog=new Dog(); myDog.setGender(myDog.MALE); myDog.printStatus(); 运行结果为: This is a dog Its gender is male 且这个时候myDog的canBark属性是true。 在构造Dog的时候,首先调用Animal的构造方法,然后给canBark赋值为true。 在重载printStatus()时,首先打印出“This is a dog”的消息,然后再调用父类中的 printStatus()方法,打印出这个动物的性别信息。 final 类和方法 由于安全性的原因,有时候需要限制某些类的继承和某些方法的重载。例如在Java基 本类库中的String类,它对编译器和解释器的正常运行有很重要的作用,不能够轻易改变, 因此要把它限定为final类,使它不能够被继承,这就保证了String类型的惟一性。同时,如 果你认为一个类定义得已经很完美,不需要再生成它的子类,这时也应把它限定为final类。 定义一个final类的格式如下: final class finalClass{ … } 同样,由于以上原因,有些方法应该限定不能被重载,我们就需要定义final()方法,final() 方法的定义格式如下: final return_type method_name(para_type para_name){ … } 2.2.2 abstract类和接口 abstract 类 与final类和方法相反,由于abstract类不能直接生成实例,所以它必须要被继承。abstract 的方法也是必须要被继承的。如果一个类声明了abstract的方法,那么它必须要被显式的声 明为abstract。 定义一个抽象类的格式如下: abstract class abstractClass{ … } 抽象方法的定义格式如下: 第 2 章 面向对象编程起步 39 abstract return_type method_name(para_type para_name){ … } 抽象类和抽象方法的作用在于给所有子类提供一个统一的接口。在Java中,还有专门 的接口的概念,下面我们就来介绍接口。 接口 Java通过接口使得处于不同层次,甚至互不关联的类可以具有相同的行为。接口就是 方法定义和常量值的集合。它的用处主要体现在下面几个方面: · 通过接口可以实现不相关类的相关行为,而不需要考虑这些类之间的层次关系。 · 通过接口可以指明多个类需要实现的方法。 · 通过接口可以了解对象的交互,而不需了解对象所对应的类。 接口的定义格式如下: interface myInterface{ interface body; } 在接口体中,声明的是多个方法的原型,定义格式如下: return_type method_name(para_type para_name,[……, para_type para_name]); 在方法体中也可以定义常量。定义常量的格式如下: type NAME=value; type可以为任意类型,常量的名字一般为大写。 接口也可以继承,如果在子接口中声明了和父接口相同的常量和方法,则父接口中的 常量被隐藏,方法被重载。 在类的声明中用implements子句来表示一个类使用某个接口,在这个类中就可以使用 接口中定义的常量,而且必须实现这个接口中定义的所有方法。如果不全部实现,则会出 现编译错误。一个类可以实现多个接口,声明的格式如下: class a implements interface1[,interface2,…,interfacen]{ //必须实现所有接口里定义的所有方法 } 接口的定义很简单,实现也很简单,但是能够在设计和编码的时候用好接口,并不是 一件容易的事情。接口是Java中最难理解的概念之一。下面通过一个例子来讲述使用接口 的好处。 Java不支持多重继承,而是用接口实现比多重继承更强的功能。多重继承指一个类可 以为多个类的子类,它使得类的层次关系不清楚。而且当多个父类同时拥有相同的成员变 量和方法时,子类的行为是不容易确定的。单一继承则清楚地表明了类的层次关系,指明 子类和父类各自的行为。接口则把方法的定义和类的层次区分开来,通过它可以在运行时 动态地定位所调用的方法。通过接口可以实现“多重继承”,且一个类可以实现多个接口。 40 Java 游戏编程导学 所有这些特性可以使得接口比多重继承更灵活,具有更强的功能。 2.2.3 多态 在Java编程时常用到多态,理解了多态,可以使我们的程序编写得更漂亮。多态是Java 中的一个重要概念。 什么叫多态 对于重载或继承的方法,Java运行时系统根据调用该方法的实例的类型来决定选择哪 个方法来调用,这就是多态。 如果一个父类有两个子类,在两个子类中都重载了一个相同的方法,如果在一个对象 中调用这个重载的方法,那么编译器就会自动判断这个对象是哪个子类的对象或者就是那 个父类的对象,然后再决定调用哪个方法:是调用重载的还是没有被重载的方法。 多态示例 下面通过一个示例来说明什么叫做多态。例子中的基类是一个abstract类,通过这个示 例,我们也可以明白abstract类的作用。 我们定义基类如下: abstract class DrawTool{ public abstract void paint(Graphics g){ } } 下面来定义两个子类,一个是用来画圆,一个是用来画方。 class CircleTool extends DrawTool{ public void paint(Graphics g){ g.drawCircle(1,1,10); } } class RectTool extends DrawTool{ public void paint(Graphics g){ g.drawRect(1,1,10,10); } } 可以这样来使用这些类: DrawTool tool1=new RectTool(); DrawTool tool2=new CircleTool(); tool1.paint(g); tool2.paint(g); 可以看到tool1和tool2都是DrawTool对象,但是它们又都是DrawTool子类的对象,所以 在调用paint()方法的时候,调用的是DrawTool子类中定义的方法。如:tool1.paint(g)将在g 第 2 章 面向对象编程起步 41 上面画一个矩形,而tool2.paint(g)将在g上面画一个圆。 这里DrawTool类是一个abstract类,它的作用就是定义一个统一的paint()方法,可以使 得所有的Tool都使用这个方法来画图形。这样可以便于我们使用所有的DrawTool,同时在 使用DrawTool的时候,不必去判断它是一个什么样的Tool(是画圆的工具还是画方的工具) 就可以拿来使用了。 2.3 包 Java中的包用来组织类之间的联系。通过包,可以控制类之间的可见性。同时,通过 包,我们解决了两个类重名的问题。包提供了一种命名机制和可见性限制机制。 2.3.1 包的定义 package是包的定义语句,放在Java源代码的第一条语句,指明该文件中定义的类所在 的包。如果没有用package指明包,则表明这个文件没有包名。 package语句的格式如下: package pakage1.[pakage2.….]; 如果一个类位于包pkg1里的包pkg2里,那么应该用下面的语句: package pkg1.pkg2; 包名一般是小写的。 Java中的包对应于文件管理系统中的目录。如果一个文件位于包java.awt.color里,则它 应该放在目录java/awt/color下面。 2.3.2 包的使用 如果使用一个包中的类,我们必须把这个类导入进来。导入语句为import,它的格式 如下: import pakage1.pakage2.class_name; 或者: import pakage1.pakage2.*; 前者是只导入包pakage1.pakage2中的class_name类,而后者则把包pakage1.pakage2中的类全 部导入。 注意:如果pakage2下面还有包,import的第二种格式并不导入pakage2下面的 包中的类。 在源程序中,如果需要使用某个类,一般情况下,我们只需要直接用类名就可以了。 0 42 Java 游戏编程导学 而仅当在我们导入的类列表中,有两个相同名字的类,例如在包pkg1中有一个名字为Date 的类,在包pkg2也同样存在一个名字为Date的类,那么如果我们在源码开头使用如下import 语句: import pkg1.*; import pkg2.*; 则在源码中使用pkg1包中的Date类的时候,必须使用pkg1.Date来明确指定我们使用的是 pkg1包中的类。 2.3.3 对包内类的访问权限 我们可以用public、protected、friendly(默认)、private来限制类之间的互访。 Java中类之间的访问可以分为以下5种: · 同一个类中 指在类的方法中访问自身的变量和方法。 · 同一个包中子类 指在包中一个类的方法里访问所在包内不同类的方法和变量,且 被访问类是访问类的父类。 · 同一个包中非子类 指在包中一个类的方法里访问所在包内不同类的方法和变量, 且被访问类不是访问类的父类。 · 不同包中的子类 指在包中一个类的方法里访问非所在包内类的方法和变量,且被 访问类是访问类的父类。 · 不同包中的非子类 指在包中一个类的方法里访问非所在包内类的方法和变量,且 被访问类不是访问类的父类。 明白了这5种访问过程,我们通过表2.1来区别public、protected、friendly(默认)、private 这4个关键字对类互访的限定。 表2.1 访问权限 同一个类中 同一个包中子类 同一个包中非子类 不同包中子类 不同包中非子类 private Y protected Y Y Y friendly Y Y Y public Y Y Y Y Y Y表示可以访问。例如:如果一个类成员的访问权限为protected,则处在同一个包中的 子类和不同包中的子类都可以访问到它,而同一包中的非子类和不同包中的非子类都不能 够访问到它。 第 2 章 面向对象编程起步 43 2.4 “幸运52”游戏 2.4.1 游戏效果说明 这个游戏是一个简单的Applet。 “幸运52”游戏是让用户对物品的价格进行估测。在对价格进行估测的时候,系统会 给出用户估测的价格是高还是低的信息。用户根据这些信息重新调整所估测的价格。 游戏的初始界面如图2.2所示。 图 2.2 游戏开始前的界面 当点击“开始游戏”按钮开始游戏后,网页就会自动调出商品的图像和显示商品的名 称,图2.3为刚刚开始的一盘游戏,其中的商品是N3310的手机。 图 2.3 开始游戏 在文本框中输入对该商品的价格的估测,然后点击“确定”按钮,这时就会弹出一个 对话框,用来告诉你所猜的价格是高了还是低了,如图2.4所示。 44 Java 游戏编程导学 图 2.4 玩家猜不中时的界面 如果你猜中了,则对话框会显示“你猜对了,恭喜你!”的消息,如图2.5所示。 图 2.5 玩家猜中后的界面 2.4.2 编写HTML页面 我们还需要编写一个用来嵌入这个Applet的HTML页面。相信大家都对HTML有一定了 解,下面先给出HTML代码,然后对用于嵌入Applet的标记进行详细讲解: HTML Test Page 第 2 章 面向对象编程起步 45 | 游戏规则: (1)点击"开始游戏"的按钮,游戏开始,系统将会把物品调入 (2)对物品的价格进行估测,直到猜对为止 |
我们通过如下的代码,将Applet嵌入到网页中去: 这里的嵌入Applet操作是通过一个html标签