ActionScript 3.0/类结构简介
关键概念
- 对象、方法和属性
- 类
- 包
- 导入
- 变量和常量
- 集成开发环境
- 编译
- 文档类
- 对象实例化
定义:类在社会中的组织
啊,类。ActionScript 项目本质上是由类组成的。(好吧,也有接口,但我们将在后面介绍。)
面向对象编程,顾名思义,是一种**编程范式**,它涉及**对象**的创建和相互作用。一个对象由两部分组成
- **属性**定义对象的特征。例如,苹果可能具有“大小”、“颜色”、“汁液含量”等属性。
- **方法**定义对象可以做什么。方法是**函数**的一个子集,我们将在后面讨论。苹果可能具有“运输”、“食用”等方法。
ActionScript 3.0 中的类看起来像这样。让我们逐一查看它的元素。
package {
import flash.display.Sprite;
import flash.events.Event;
/**
* @author WikibooksOverlord
*/
public class Main extends Sprite{
private const HELLO_WORLD:String = "Hello, world!";
private var _username:String = "Daniel";
public function Main():void{
if (stage) init(null);
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
//You can start changing from this line.
trace(HELLO_WORLD); //This line outputs 'Hello, world!' for now.
trace("Your name is " + name + ".");
//Don't touch anything below this line.
}
}
}
package {
**包**是特定目录中的一组类和其他内容。上面的代码行称为**包定义**。例如,名为“fruit”的包可能包含 Fruit 和 Apple 等类。
这里的“package”一词是**关键字**。关键字是语言用来执行基本操作的词语。
在我们的例子中,我们的类存储在主包中,因此我们不需要在“package”关键字之后添加其他信息。为了指定我们的类位于“food”包中,我们可以在“package”关键字后追加包名
package food{
如果“food”包中有一个“fruit”包,我们用点(“.”)分隔较大的包和较小的包
package food.fruit{
除了提高组织性之外,包中的类可以与其他包中的类具有相同的名称。包名是区分它们的方法。你可以在 applicances.Iron 和 materials.Iron 中分别拥有一个名为 Iron 的类。
注意,定义后的左大括号与类文件末尾的右大括号相匹配。程序中的其他所有内容都设置为包含在这个**块**中。块是逻辑上的“命令”或**指令**单元,用一对大括号括起来。按照惯例,块中的所有内容都应该缩进,如上所示。缩进极大地提高了代码的可读性,但对于程序运行不是必需的。(实际上,你可以将类中的所有内容放在一行中,它仍然可以工作;但是,代码将不再可读。)
还要注意,所有包名都以小写字母开头,而所有类名都以大写字母开头。这是一个普遍接受的惯例,应该遵循,即使代码仍然可以工作,你也可以不遵守。
import flash.display.Sprite;
import flash.events.Event;
如果我们想使用其他包中的类,例如**标准库**,则需要**导入语句**。在本例中,我们从标准库中导入了两个包:flash.display.Sprite 和 flash.events.Event。标准库是一堆代码,控制着我们的 Flash 操作的基本操作,例如文本、图形、声音等等。标准库有一些替代方案,但在这里不作介绍。
有时,如果我们很懒,可以使用星号 (*) 导入包中的所有内容
import flash.events.*;
如你所见,导入语句的语法是“import”关键字,后跟包的路径。请注意,虽然 flash.display.Sprite 和 flash.events.Event 是预定义的类,但它们不是关键字,因为它们属于标准库而不是语言本身。
导入后,我们可以以任何我们想要的方式使用这些类。
类结构:社会中类的组织。
public class Main extends Sprite{
在此语句中,“public”关键字告诉我们,即使我们位于当前包之外,也可以使用该类。这被称为**命名空间属性**。命名空间处理**访问控制**;也就是说,如何访问该类(令人惊讶的是)。类只有两种可能的命名空间属性
public
告诉我们,我们可以在任何地方使用该类。internal
告诉我们,我们可以在同一个包的类中使用该类。这是默认属性,因此,如果你完全跳过命名空间属性,命名空间将自动设置为“internal”。
在命名空间属性之后,我们发现了另一个关键字“class”。然后我们看到了类标识符 Main。(**标识符**是“名称”,在命名空间内唯一标识某物。某物的完整名称是命名空间加上标识符。这将在后面介绍;现在,你只需将“标识符”一词视为特殊的“名称”。)
在那之后,我们看到了关键字“extends”,后跟类名“Sprite”。这表明我们的 Main 类是 Sprite 类的**子类**。稍后,当我们了解 Main 类到底是什么以及子类是什么时,你将理解我们在这一行中做了什么。现在,就先把它当作理所当然吧。
类成员包括属性和方法。属性可以是**常量**(永不改变)或**变量**(会改变)。
private const HELLO_WORLD:String = "Hello, world!";
private var _username:String = "Daniel";
“private”是我们用于类成员的另一个命名空间属性。有四个可能的命名空间属性(除了用户定义的属性之外)
public
告诉我们,我们可以在任何地方使用该成员。internal
告诉我们,我们可以在同一个包的类中访问该成员。这是默认属性,因此,如果你完全跳过命名空间属性,命名空间将自动设置为“internal”。稍后,我们将学习访问其他类的成员。protected
告诉我们,只有类本身及其子类才能访问该成员。private
是最严格的属性。只有类本身才能访问该成员。即使是子类也没有权限。
一般来说,我们选择的属性应该尽可能地严格。
在上面的代码行中,我们定义并初始化了一个常量和一个变量。在下一章中,我们将介绍这两行代码实际上做了什么。
以下是我们的**方法定义**
public function Main():void{
if (stage) init(null);
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
//You can start changing from this line.
trace(HELLO_WORLD); //This line outputs 'Hello, world!' for now.
trace("Your name is " + name + ".");
//Don't touch anything below this line.
}
在上面,我们可以看到两个方法定义:Main 和 init。Main 被称为类的**构造函数**。当类初始化时,将调用此方法进行设置。请注意,构造函数始终是 public 的。init 是一个私有函数,只能在类内部调用。
这段代码片段中有很多你还不理解的东西。别担心——我们会在第一部分介绍所有内容。现在,就先把它当作理所当然吧!
**注释**不会改变程序的工作方式,但它是向程序添加信息(无论是为了你自己还是其他程序员)的有效方法。有两种类型的注释
第一种类型的注释以 // 开头,并添加到行尾。它不能扩展到一行以上。这种类型的注释通常用于解释代码。
trace(HELLO_WORLD); //This line outputs 'Hello, world!' for now.
trace("Your name is " + name + ".");
//Don't touch anything below this line.
第二种类型的注释,用 /* 和 */ 包围,可以跨越多行。/* 标记注释的开始,*/ 标记注释的结束。这种类型的注释也可以添加到一行的中间。它们被广泛用于诸如待办事项列表和版权信息之类的元素。这是一个例子
/*Lorem ipsum
The quick brown fox
Jumped over the lazy dog */
正如您可能已经注意到的,这种类型的注释确实出现在我们的 Main 类中。但是,它看起来有点不同。这是因为它是一个 **Javadoc 注释**,将在稍后介绍。
/**
* @author WikibooksOverlord
*/
有时,我们需要暂时“隐藏”一些代码。这可以通过将代码转换为注释来实现。这种技术被称为 **注释掉**。
我们在上面创建的 .as 文件只是一个文本文件;它没有为我们做任何建设性的工作。为了使程序工作,我们需要一个 **编译器**。在开始编译器之前,让我们看一下用于 ActionScript 编码的不同 **集成开发环境** (IDE)。尽管您可以使用文本编辑器用 ActionScript 编码并将其输入到命令行编译器中,但不建议这样做。集成开发环境通常包含以下功能
- 项目管理系统,用于组织项目使用的资源和文件。
- **语法高亮**是一种功能,其中代码的不同部分被着色以提高代码可读性。在这本书中,语法着色是通过 MediaWiki 软件实现的。
- **代码提示**通过提醒您接下来需要输入的内容来加快开发速度。
- **语法检查器**用于检查您的语法。
- 内置 **编译器** 和 **调试实用程序** / **调试器**,允许您在 IDE 中编译和调试。我们将在稍后介绍调试器。
一个好的 IDE 还提供了用于编辑相关标记语言的功能,例如 **MXML**(这超出了本书的范围,但对于 ActionScript 界面非常有用)。
Flash 的常见 IDE 包括
- **Flash Professional**:第一个 Flash 制作软件,Flash Professional 将动画和编码合并到一个软件中。但是,它的 IDE 功能因此受到限制。Flash CS3 及更高版本支持 AS3。
- **Eclipse**:一个通用的 IDE,用于许多不同的语言,包括 ActionScript。
- **Flash Builder**:一个基于 Eclipse 的专有 IDE。
- **FlashDevelop**:一个面向 ActionScript 的开源 IDE。它提供了诸如 SharedObject 跟踪之类的便利功能,还包含高级代码提示功能。
在这本书中,我们将提供有关 FlashDevelop 的说明。如果您使用其他 IDE,请参阅相关文档。
计算机只理解机器语言。ActionScript 是一种人类可读的语言,但不是计算机可读的语言。语言级别越高,它就越接近计算机系统。机器代码和汇编语言是最低级的语言,因为它们直接控制计算机系统的不同部分。高级语言必须转换为低级语言,才能被计算机理解。编译器是一个程序,它将代码从高级编程语言转换为低级语言。
对于 ActionScript,它稍微复杂一些。ActionScript 编译器将我们的 ActionScript 编译为一种称为 **ActionScript 字节码** (ABC) 的低级语言。然后,ABC 与资源(音乐、图形等)打包在一起,形成另一个称为 **Shockwave Flash 文件** (SWF) 的文件,这是由 SWF 编译器执行的魔法。Flash Professional 使用名为 **Flash 编译器** 的 SWF 编译器,而 FlashDevelop、Flash Builder 等则使用名为 **Flex 编译器** 的 SWF 编译器。
然后,ABC 由一个称为 **Flash Player** 的 **运行时环境** 使用嵌入的资源执行。运行时环境将 ABC 编译为控制计算机硬件的机器语言。这种转换是实时执行的,被称为 **即时编译**。
编译有两种类型:**调试构建** 和 **发布构建**。调试构建是您在项目开发期间构建的。一旦您的项目准备好编译,您将编译发布构建,它更快、更轻量级。为了在构建之间切换,FlashDevelop 在顶部有一个工具栏,其中有一个下拉菜单,当您将鼠标悬停在上面时会显示工具提示“选择配置”。
现在打开您选择的 IDE 并创建一个新项目。在 FlashDevelop 中,点击项目 > 新建项目 > AS3 项目。为您的项目命名您想要的任何名称。现在将以下文件夹添加到项目的主文件夹中(如果它们还不存在)
- **src** 包含项目的源代码。
- **bin** 包含项目的已编译二进制文件(即 SWF 文件,如果您仔细阅读了上一节)。
接下来,在 IDE 的“项目”屏幕中,找到 Main 类。如果它不存在,请创建一个。将上面的代码直接复制到文本文件中。将其设置为文档类(在 FlashDevelop 中,右键单击项目窗口中的文件并选中“文档类”)。
现在,将编译器设置为编译到 \bin\MyFile.swf(项目 > 属性 > FlashDevelop 中的输出)。现在编译并运行项目(CTRL + ENTER 或 FlashDevelop 中的蓝色“播放”按钮)。
如果您已正确执行所有操作,您应该在 IDE 的输出屏幕中看到以下内容
Hello, world! Your name is Daniel.
启动 Flash 应用程序后,发生的第一件事是
- 文档类的实例被实例化。
- 新实例被添加到舞台上。
现在,您可能完全困惑了。不要让这些新词吓倒您!我们将逐一了解所有内容。
假设我们现在有一个名为 Apple 的类。幸运的是,在编程世界中,您不需要花时间种植苹果。您所需要做的就是创建 Apple 类的 **实例**。要创建 200 个苹果,请创建 Apple 类的 200 个实例。创建实例称为 **实例化**。
通常,对象实例化是使用 new
关键字完成的。例如,表达式 new Apple()
实例化一个新的苹果。(注意,这里可以省略圆括号。)但是,我们这里的 Main 类是一个 **文档类**。这意味着运行时环境非常友好地为我们实例化了 Main 类。