了解有关 Java 包、变量的概念,以及对象通过方法相互交互的方式。
在 Wombat 对象基础知识 和 Wombat 类基础知识 这两篇文章中,您学习了关于对象、类、方法,以 及语言和语法的基础知识。在初级开发人员系列的第 3 部分,您将学习:如何编写依赖其他 Java 类(或 Java API)的 Java 应用程序、什么是变量、如何使用变量,以及对象通过方法相互交互的方式。
本文中,需要在计算机中安装以下软件:
Java SE 软件
Greenfoot
本文面向对 Java 编程感兴趣的任何读者,无需编程经验。在开始阅读本文之前,建议您阅读并遵循 Wombat 对象基础知识 和 Wombat 类基础知识 中的有关说明。
在 Ants 中查看包和变量
在本教程中,通过 Scenario 菜单打开 Ants 场景,然后选择 Open。应该可以看到 scenarios 文件 夹。选择 ants 并单击 Open,如图 1 所示:
图 1. 打开 Ants 场景
Ants 场景将显示在新窗口中。如果您在画面中没有看到沙色的界面,单击场景主画面底下的 Compile All 按钮。
单击 Run,当蚂蚁离开蚁丘寻找食物堆时,请仔细观察。当蚂蚁发现食物并运回蚁丘时,它们就创建 了气味路径,或者相当于 pheromone 路径,随着更多的蚂蚁发现了食物的路径并返回蚁丘,气味路径变 得越来越清晰。和 Wombat 场景一样,可以在场景中放置更多的蚂蚁或蚁丘。在 ants 场景中单击 Run, 应该能看到如图 2 所示的内容。
图 2. 运行 Ants 场景
导入声明和包
右键单击 Actor 类下方的 Ant 对象,并选择 Open Editor。注意代码的第一行:
import greenfoot.*; // (World, Actor, GreenfootImage, and Greenfoot)import
java.util.Random;import java.util.List;import java.util.Collection;import
java.util.Iterator;
这些语句称为导入声明。使用导入声明,Java 应用程序可以使用 Java API 中已有的类、其他开发人 员或自己创建的类。
第一个声明表明此应用程在 greenfoot package 中。Java 类通过包组织在一起。您可以使用很多包 ,这就如同类可以处理数学问题、可在 Collection 对象中组织数据和可用于过程的迭代或循环一样。换 句话说,包通过函数对类进行分类。基础类在 java.lang 包 中,读取和写入类(输入和输出)在 java.io 包 中,等等。必须在类的第一行声明包。
Java API 库非常庞大,其中提供了许多包供您使用。并且,您需要自己熟悉有哪些类可用。为此,最 好的方式是花些时间去阅读 API 文档。在本文中,查阅 java.util package。在该页面的左侧列表中, 请注意 Random、List、Collection 和 Iterator 类。单击这些类的链接并阅读有关内容。看看您能否指 出它们在此应用程序中所完成的功能。注意为每个类所列出的方法,看看您能否在 Ants Actor Classes 的代码中找出那些使用过的方法。您也可以在 Java 教程 中阅读更多有关这些类的信息。
变量和字段
随后,Ant 类中将出现 public class Ant extends Actor 行。从前面的文章可知,这是类声明语句 ,它告诉您,此类名称为 Ant,并且是从 Actor 类继承下来的。
随后,你将在类中看到常规的语句,它在代码行之间用 /** 和 */ 符号标记。用 /** 和 */ 标记的 语句是开发人员插入的注释,这样,就能更容易理解代码。必须用/** 和 */ 或 // 符号标记注释,这样 ,编译器就不会尝试将这些语句读取为 Java 代码。
请看以下代码块,阅读注释,该注释对代码描述的功能作出说明:
/** Random number generator */
private static final Random randomizer = AntWorld.getRandomizer();
/** Every how many steps can we place a pheromone drop? */
private static final int MAX_PH_LEVEL = 18;
/** How long do we keep direction after finding pheromones? */
private static final int PH_TIME = 30;
/** The speed at which the ant moves -- in pixels per update */
private static final int SPEED = 3;
// Current movement
private int deltaX = 0;
private int deltaY = 0;
/** Location of home anthill */
private AntHill homeHill;
/** Indicate whether we have any food with us. */
private boolean carryingFood = false;
/** How much pheromone do we have right now? */
private int pheromoneLevel = MAX_PH_LEVEL;
/** How well do we remember the last pheromone -- larger number: more recent.
*/
private int foundLastPheromone = 0;
所有的代码行都使用 变量,并且这些特殊的变量在此 Ant 类中定义了 field。字段声明由三个部分 构成,依次是:
零个或多个修饰符,例如 public 或 private
字段类型
字段名称
但在理解字段之前,需要了解更多有关变量的内容。变量是什么?在程序设计中,variable 需要被赋 值,该值要么改变,要么不改变。因为它们表示的值经常发生改变,故称为变量。在上面的代码中,变量 SPEED 被赋值为 3。赋给变量的值写在等号的右边,变量写在左边。
这些特殊的变量定义了对象的状态。这就如同现实世界中的对象,现实中,球的状态要么是红色的, 要么是直径为 3 英尺。您也许会将变量 dog 的状态赋值为睡着或醒的。对 Ant 类而言,所指的状态为 :每只蚂蚁在某个方向的移动速度为 3 个像素。
蚂蚁用 Pheromones 气味寻找食物,并提示其他蚂蚁哪里能收集食物。在此应用程序中,Ant 类定义 了有关信息素的层次信息,以及蚂蚁在碰面时通过字段变量如何操作。例如,MAX_PH_LEVEL 字段定义了 滴下一个信息素时,蚂蚁能移动的最大步数;foundLastPheromone 定义:通过使用高或低的编号,蚂蚁如 何适当地记忆信息素。
通常,将变量的初始值设为 0 ,或为空。然后,随着用户运行程序,这些值将发生改变。
变量类型
您也许已经注意到,在该类和其他类的变量前面的关键字 private、static 和 final。这些关键字定 义了变量的类型。无关键字的变量称作 instance variables,该变量的值与类中的每个 instance 值都 不相同——对每个对象而言,也是这样。另一方面,static variable 说明即使对类进行了多次实例化, 或者创建了实例,此变量仅存在一个副本。
Local variables 是那些仅在一个方法或代码块中使用的变量,这在本文的前面已经提到了。
Access modifiers 声明变量要么是 public 类型,要么是 private 类型。在 Food 中,所有的变量 都被声明为 private 类型,这说明仅能在 Food 类中访问这些变量。如果变量被声明为 public 类型, 则可以从所有类中访问该变量。
Ant 对象通过方法与 Food 对象进行交互
现在已经声明了变量,接下来就可以在方法中使用变量,为场景做些工作。在 Ant 类中向下滚动,浏 览已定义的方法。您将注意到,现在,已经在方法中使用了类开头所设置的变量。还可以看到,新变量可 能仅用于某个特定的方法。前面已经提到,这些变量称为 local variables。
蚂蚁场景中的点用于收集食物并将其运回蚁丘。注意 Ant 类中的 checkFood 方法:
public void checkFood()
{
Food food = (Food) getOneIntersectingObject(Food.class);
if (food != null) {
takeFood(food);
}
}
在此方法中,声明了一个 Food 型变量 food。在 Java 编程中,类名通常用大写字母表示,变量名用 小写字母表示。通过方法,ants 对象就能与 food 对象交互,如图 3.所示:
图 3. Ants 与 Food
文件看一下 Food 类。 在 Ants 场景中,右键单击 Actor Classes 下面的 Food 类列表,选择 Open Editor。
实际上,food 类只是放在那儿,并不起什么作用,只是通过自身的变量定义 Food 。
private static final int SIZE = 30;
private static final int HALFSIZE = SIZE / 2;
private static final Color color1 = new Color(160, 200, 60);
private static final Color color2 = new Color(80, 100, 30);
private static final Color color3 = new Color(10, 50, 0);
private int crumbs = 100;
注意:这些字段建立了 food 的 size 和 color。通过 Color 类定义 Color,说明每个 color 都是 一个对象,确切的 color 是通过 RGB color model 定义的。用整数 (int) 创建 food 堆的 size,表示 某个特定 color 的像素数目。所有的变量都是 private 类型,说明它们仅能在此类中使用,同时它们又 是 static 类型,因此,即使对此类进行多次实例化 ,也仅存在一个副本。
向下滚动 Color 类,注意此类中的方法。场景运行后,蚂蚁发现并搬运食物,食物的外观必须发生变 化。为创建蚂蚁和食物堆之间的交互作用,takeSome 方法定义搬运食物的数量,并调用 updateImage 方 法,这样,食物堆的外观就会发生变化,同时我们也能看到这些变化。
randomCoord 方法在食物堆图像上随机撒播彩色点,越来越多的彩色点向中心聚集。此方法在食物堆 中产生随机位置(放置小绿点表示食物个体小块)。这是基于随机数的 Gaussian 分布 函数 (nextGaussian),该方法使数字与 0 逼近的可靠性更高(也称作“常态分布”或“正态分布”)。结果, 食物小块并不是均匀地分布在矩形画面表面,很可能是向中间聚集,这样就形成了更多的堆。
结束语
在本文中,您学习了包如何组织类,以及如何在类的头部包含 import 语句。还学习了有关变量及其 类型,以及对象如何通过方法与其他类交互的内容。在 Greenfoot 中打开其他场景,了解了每个场景对 象的类代码。目睹了什么是变量定义、什么是方法之间的交互,以及通过查看代码学习了其他一些内容。 尝试并改变其中的一些方法,看看您能否改变对象的行为。您也可以在 Internet 上查看有关 Greenfoot 更多场景的信息,有些场景非常复杂且精致,不妨把它们下载下来。