由于 ActionScript 3.0 是在以前版本的 ActionScript 基础上构建的,了解 ActionScript 对象模型的发展过程可能有所帮助。ActionScript 最初作为早期版本的 Flash Professional 的简单编写脚本机制。后来,编程人员开始使用 ActionScript 构建更加复杂的应用程序。为了迎合这些程序员的需要,每个后续版本都添加了一些语言功能以帮助创建复杂的应用程序。
ActionScript 1.0
ActionScript 1.0 是在 Flash Player 6 和更早版本中使用的语言版本。即使在这个早期开发阶段,ActionScript 对象模型也是建立在基础数据类型对象的概念的基础上。ActionScript 对象是由一组
属性
构成的复合数据类型。讨论对象模型时,术语
属性
包括附加到对象的所有内容,如变量、函数或方法。
尽管第一代 ActionScript 不支持使用
class
关键字定义类,但是可以使用称为原型对象的特殊对象来定义类。Java 和 C++ 等基于类的语言中使用
class
关键字创建要实例化为具体对象的抽象类定义,而 ActionScript 1.0 等基于原型的语言则将现有对象用作其他对象的模型(或原型)。基于类的语言中的对象可能指向作为其模板的类,而基于原型的语言中的对象则指向作为其模板的另一个对象(即其原型)。
要在 ActionScript 1.0 中创建类,可以为该类定义一个构造函数。在 ActionScript 中,函数不只是抽象定义,还是实际对象。您创建的构造函数用作该类实例的原型对象。以下代码创建一个名为 Shape 的类,还定义一个名为
visible
的属性,该属性默认情况下设置为
true
:
// base class
function Shape() {}
// Create a property named visible.
Shape.prototype.visible = true;
此构造函数定义可以使用
new
运算符实例化的 Shape 类,如下所示:
myShape = new Shape();
就像
Shape()
构造函数对象用作 Shape 类实例的原型一样,它还可以用作 Shape 的子类(即扩展 Shape 类的其他类)的原型。
创建作为 Shape 类的子类的类的过程分两个步骤。首先,通过定义类的构造函数创建该类,如下所示:
// child class
function Circle(id, radius)
{
this.id = id;
this.radius = radius;
}
然后,使用
new
运算符将 Shape 类声明为 Circle 类的原型。默认情况下,创建的所有类都使用 Object 类作为其原型,这意味着
Circle.prototype
当前包含一个通用对象(Object 类的实例)。要指定 Circle 的原型是 Shape 而不是 Object,请使用以下代码更改
Circle.prototype
的值,使其包含 Shape 对象而不是通用对象。
// Make Circle a subclass of Shape.
Circle.prototype = new Shape();
Shape 类和 Circle 类现在通过通常所说的
原型链
的继承关系联系在一起。下图说明了原型链中的关系:
每个原型链末端的基类是 Object 类。Object 类包含一个名为
Object.prototype
的静态属性,该属性指向在 ActionScript 1.0 中创建的所有对象的基原型对象。该示例原型链中的下一个对象是 Shape 对象。这是因为从不显式设置
Shape.prototype
属性,所以它仍然包含通用对象(Object 类的实例)。此链中的最后一个链环是 Circle 类,该类链接到其原型 Shape 类(
Circle.prototype
属性包含 Shape 对象)。
如果您创建 Circle 类的实例(如以下示例所示),该实例会继承 Circle 类的原型链:
// Create an instance of the Circle class.
myCircle = new Circle();
回想一下,该示例包括一个名为
visible
的属性作为 Shape 类的成员。在本示例中,
visible
属性并不作为
myCircle
对象的一部分,只是 Shape 对象的一个成员,但以下代码行的输出却为
true
:
trace(myCircle.visible); // output: true
运行时能够沿着原型链检查
myCircle
对象是否继承了
visible
属性。执行此代码时,运行时首先在
myCircle
对象的属性中搜索名为
visible
的属性,但未发现这样的属性。运行时接下来在下一个
Circle.prototype
对象中查找,仍未发现名为
visible
的属性。运行时继续检查原型链,最终发现了在
Shape.prototype
对象上定义的
visible
属性,并输出该属性的值。
为简单起见,省略了原型链的许多细节和复杂性。目标只是提供足够信息来帮助您了解 ActionScript 3.0 对象模型。
ActionScript 2.0
在 ActionScript 2.0 中引入了
class
、
extends
、
public
和
private
等新关键字,通过使用这些关键字,您可以按 Java 和 C++ 等基于类的语言用户所熟悉的方式来定义类。ActionScript 1.0 和 ActionScript 2.0 中的基础继承机制是相同的,了解这一点很重要。ActionScript 2.0 只是增加了定义类的新语法。在该语言的两个版本中,原型链的作用方式是一样的。
ActionScript 2.0 中引入了新语法(如以下摘录中所示),可允许以多数程序员认为更直观的方式定义类:
// base class
class Shape
{
var visible:Boolean = true;
}
注意,ActionScript 2.0 还引入了用于编译时类型检查的类型注释。使用类型注释,可以将上个示例中的
visible
属性声明为应只包含布尔值。新
extends
关键字还简化了创建子类的过程。在下面的示例中,通过使用
extends
关键字,可以一步完成在 ActionScript 1.0 中需要分两步完成的过程:
// child class
class Circle extends Shape
{
var id:Number;
var radius:Number;
function Circle(id, radius)
{
this.id = id;
this.radius = radius;
}
}
构造函数现在声明为类定义的一部分,还必须显式声明类属性
id
和
radius
。
ActionScript 2.0 中还增加了对接口定义的支持,以使您能够使用为对象间通信正式定义的协议来进一步改进面向对象的程序。