actionscript3
让我们面对现实:客户端对于Java程序员而言并不是一个友好的地方。 带有applet,Swing和JavaFX的客户端上的Java技术取得的成功有限。 JavaScript尽管有其名称,但几乎与Java语言完全不同。 和Adobe Flash一样,就像JavaScript。 还是? 几年前,Flash可能像JavaScript一样,但是随着ActionScript 3的出现,发生了很多变化。 而且我认为您会发现很多喜欢的东西。
首先,现在已经强烈键入了ActionScript(Adobe Flex和Flash的编程语言)。 它还具有一流的面向对象,包括类和接口。 它具有您在Java中找不到的其他功能-尤其是get
和set
属性的功能以及称为ECMAScript for XML (E4X)的语言扩展,它将任何XML文档转换为可以用点运算符引用的对象,就像常规的对象。
本文向您介绍了ActionScript 3的基础知识,并展示了它与您习惯使用的Java环境的比较。 最后,您应该已经放弃了对ActionScript的任何先入之见,并且对使用它有兴趣。 Flex,Flash和ActionScript的一大优点是可以免费使用。 只需下载Adobe Flex Builder 3即可上手。 Flex Builder是一个复杂的集成开发环境(IDE),它不是免费的应用程序,但用于构建Flash应用程序的Flex软件开发工具包(SDK)却不是。
警告阅读本文的语言纯粹主义者:我不是语言专家,所以我可能会掩盖一些语言细节。 我也不打算在本文中介绍ActionScript 3中的所有内容。 如果您要这样做,则可以找到许多有关ActionScript 3的好书。 我能做的就是给你的语言的感觉 。 开始。
类和接口
与Java一样,所有内容实际上都是ActionScript 3中的对象。有一些基本类型(如整数),但除此之外,所有内容都是对象。 类似地,像Java一样,存在命名空间和包,例如com.jherrington.animals ,在这种情况下,这意味着公司/杰克·赫灵顿/动物类 。 您可以将类放入默认名称空间,但是最好控制您的名称空间。
与Java一样,要定义类,请使用class关键字。 这是一个例子:
package com.jherrington.animals
{
public class Animal
{
public function Animal()
{
}
}
}
在这种情况下,我将使用当前不执行任何操作的构造函数来定义Animal
类。
我可以添加一些成员变量并非常轻松地完善构造函数,如下所示:
package com.jherrington.animals
{
public class Animal
{
public var name:String = "";
private var age:int = 0;
private function Animal( _name:String, _age:int = 30 )
{
name = _name;
age = _age;
}
}
}
在这里,我定义的是Animal
对象具有两个成员变量。 名称(是一个公共字符串)和年龄(一个私有整数)。 (显然,动物对它们的年龄感到害羞。)构造函数采用一个或两个值:单独的名称或名称和年龄。 您可以通过在函数声明中添加参数来为其提供默认值。
您对这段代码的注意是键入是从Java倒置的。 在Java中,类型优先。 在ActionScript中,它排在第二位。 这是因为强类型键入是ActionScript的附加组件。 因此,要支持较早的非类型代码,类型应位于变量名称之后。
让我们通过添加一些方法来扩展示例:
package com.jherrington.animals
{
import flash.geom.Point;
public class Animal
{
public var name:String = "";
private var age:int = 0;
private var location:Point = new Point(0,0);
public function Animal( _name:String, _age:int = 30 )
{
name = _name;
age = _age;
}
public function moveTo( x:int, y:int ) : void {
location.x = x;
location .y = y;
}
public function getLocation( ) : Point {
return location;
}
}
}
如您所见,我添加了另一个Point
类型的私有成员变量location
,它是从Flash的几何包中导入的。 并且我添加了两个与该位置一起使用的方法: moveTo
(移动动物)和getLocation
(返回当前位置)。
现在,这是一种获取和设置值的Java方法。 如下面的代码所示,ActionScript的实现方式更加简洁:
package com.jherrington.animals
{
import flash.geom.Point;
public class Animal
{
public var name:String = "";
private var age:int = 0;
private var myLocation:Point = new Point(0,0);
public function Animal( _name:String, _age:int = 30 )
{
name = _name;
age = _age;
}
public function set location( pt:Point ) : void {
myLocation = pt;
}
public function get location( ) : Point {
return myLocation;
}
}
}
在这里,我使用的是get
和set
函数,这些函数在客户端代码获取或设置成员变量location
的值时调用。 对于客户端,location变量看起来就像常规成员变量。 但是,您可以设置所需的任何代码来响应成员变量设置并处理变量的get
。
你怎么利用这个? 您可以添加在位置更改时触发的事件。 检查以下代码:
package com.jherrington.animals
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.geom.Point;
public class Animal extends EventDispatcher
{
public var name:String = "";
private var age:int = 0;
private var myLocation:Point = new Point(0,0);
public function Animal( _name:String, _age:int = 30 )
name = _name;
age = _age;
}
public function set location ( pt:Point ) : void {
myLocation = pt;
dispatchEvent( new Event( Event.CHANGE ) );
}
public function get location( ) : Point {
return myLocation;
}
}
}
现在,我指定Animal
类是event dispatcher
-即,客户端可以从中监听事件的对象。 然后,当位置更改时,我将调度一个新事件。
这是创建动物的客户端代码,设置其自身以监视更改事件,然后更改其位置:
var a:Animal = new Animal();
a.addEventListener(Event.CHANGE, function( event:Event ) : void {
trace( "The animal has moved!" );
} );
a.location = new Point( 10, 20 );
当动物移动时,此代码会显示一条跟踪消息。 您可以在ActionScript中定义所需的任何类型的消息。 大多数类都是EventDispatchers,并且具有可以为其添加侦听器的事件。
介面
与Java一样,ActionScript 3语言也支持构建器接口并使用类来实现它们。 下面显示的界面是我们可以从Animal
类获得的示例:
package com.jherrington.animals
{
import flash.geom.Point;
public interface IAnimal
{
function get name() : String;
function set name( n:String ) : void ;
function get location() : Point;
function set location( pt:Point ) : void ;
}
}
在这种情况下,我为可以设置和获取的接口定义了两个成员变量。 是的,您可以在ActionScript界面中定义方法和成员变量。 多么酷啊?
为了实现该接口,我对Animal
类进行了一些更改。 您可以在下面的代码中看到这一点:
package com.jherrington.animals
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.geom.Point;
public class Animal extends EventDispatcher implements IAnimal
{
private var myName:String = "";
public function get name() : String
{
return myName;
}
public function set name( n:String ) : void
{
myName = n;
dispatchEvent( new Event( Event.CHANGE ) );
}
private var myLocation:Point = new Point(0,0);
public function set location ( pt:Point ) : void {
myLocation = pt;
dispatchEvent( new Event( Event.CHANGE ) );
}
public function get location( ) : Point {
return myLocation;
}
public function Animal( _name:String )
{
name = _name;
}
}
}
当然,我可以添加特定于此类的变量和方法,或者实现除IAnimal
接口之外的IAnimal
接口。 但是,与Java一样,我只能从一个基类继承。
静态和常数
ActionScript 3支持常量和静态成员变量以及静态方法。 常量很容易定义,如下面的代码所示:
public const MINIMUM_AGE:int = 0;
public const MAXIMUM_AGE:int = 2000;
常量可以是您喜欢的任何类型,但是必须在编译时进行定义。 如果您要对它们进行范围划分,它们也可以是受保护的或私有的。
为了演示静态函数,我在Animal
类中展示了一个工厂方法:
public static function buildAnimal( n:String ) : IAnimal {
return new Animal( n );
}
使用静态方法的另一种方法是在Singleton模式中。 下面是Animal
类的Singleton factory
类的示例:
package com.jherrington.animals
{
public class AnimalFactory
{
private static var _factory:AnimalFactory = new AnimalFactory();
public static function get instance() : AnimalFactory {
return _factory;
}
public function build( n:String ) : Animal {
return new Animal( n );
}
}
}
要调用它,我使用instance
成员变量来获取单个factory
对象:
private var b:Animal = AnimalFactory.instance.build( " Russell " );
这将使用Singleton工厂对象创建名称为Russell的新动物。
遗产
为了演示继承,我展示了三个接口和类。 第一个接口是我之前显示的IAnimal
类。 第二个是Animal
类,第三个是名为Dog
的派生类,该类重写方法。
接口IAnimal
如下所示:
public interface IAnimal
{
function get name() : String;
function set name( n:String ) : void ;
function move( x:int, y:int ) : void ;
}
通过将其返回到name
成员变量和move()
方法,我对其进行了一些简化。 接口的第一个实现是Animal
类:
public class Animal extends EventDispatcher implements IAnimal
{
private var myName:String = "";
public function get name() : String
{
return myName;
}
public function set name( n:String ) : void
{
myName = n;
dispatchEvent( new Event( Event.CHANGE ) );
}
public function Animal( _name:String )
{
name = _name;
}
public virtual function move( x:int, y:int ) : void
{
}
}
然后, Dog
类通过具有自己的构造函数和对move()
方法的重写来建立在Animal
类上:
public class Dog extends Animal
{
public function Dog(_name:String)
{
super (_name);
}
public override function move( x:int, y:int ) : void
{
trace ( 'Moving to '+x+', '+y );
}
}
这很像Java代码,因此在ActionScript中实现面向对象的设计时,您应该真正有宾至如归的感觉。
运算符和条件
ActionScript中的运算符与Java中的运算符完全相同。 同样,数学运算符和布尔运算符相同:
var a:int = 5;
var b:int = 6;
var c:int = a * b;
c *= 10;
var d:Boolean = ( c > 10 );
var e:int = d ? 10 : 20;
这些示例显示了一些不同的运算符。 在这些示例中,ActionScript和Java之间的唯一区别是用于定义变量的语法。
像运算符一样,两种语言之间的条件运算完全相同,例如:
if ( a > 10 ) {
trace ( 'low' );
}
else if ( a > 20 ) {
trace ( 'high' );
}
else {
threw new Exception( "Strange value" );
}
显示了条件语法以及如何引发异常。 异常处理在Java中完全相同。 您可以定义自己的异常类型,也可以只使用标准的Exception类。
try
, catch
和finally语法显示在以下示例中:
try
{
location = new Point( -10, 10 );
}
catch ( Exception e )
{
trace ( e.toString() );
}
finally
{
location = null ;
}
此代码尝试设置位置,并在出现问题时找出错误。 无论如何,该位置最后都将设置为null。
迭代器
ActionScript 3没有强类型的容器,但是使用数组和哈希表仍然很容易。 这是使用for循环迭代数组的示例:
var values:Array = new [ 1, 2, 5 ];
for ( var i:int = 0; i < values.length; i++ )
trace ( values[i] );
但这并不是您真正想要在ActionScript中迭代数组的方式。 最佳方法是对每种语法使用,如下一个示例所示:
var values:Array = new [ 1, 2, 5 ];
for each ( var i:int in values )
trace ( i );
此代码遍历数组中的每个元素,并沿途将i的值设置为每个元素。
要创建哈希表,请在ActionScript中使用基本的Object类型:
var params:Object = { first: 'Jack' , last: 'Herrington' };
for ( var key:String in params )
trace ( key+' = '+params[key] );
ActionScript在JavaScript中的起源意味着基本对象类型是基于插槽的容器,您可以轻松地将其用作哈希表。
常用表达
正则表达式直接嵌入到ActionScript的基本语法中。 例如,此代码:
if ( name.search( /jack/ i ) )
{
trace ( 'hello jack' );
}
对字符串执行简单检查。
此代码使用正则表达式执行拆分操作:
var values:String = "1,2,3";
for each ( var val:String in values.split(/,/) ) {
trace ( val );
}
是否应该在核心语法中嵌入正则表达式仍有待商.。 Java的设计师显然认为这些表达式应该放在外部库中。 但是我认为它们足够有用,因此应该像在ActionScript中一样进行集成。
E4X
XML已被广泛使用,因此ActionScript支持将其内置在语言语法中。 如果您是XML迷,那您一定会喜欢的。 看看这个:
var myData:XML = <names>
<name>Jack</name>
<name>Oso</name>
<name>Sadie</name>
</names>;
for each ( var name:XML in myData..name ) {
trace ( name.toString() );
}
这段代码定义了一个XML文档,然后对其进行搜索并打印出所有 标签。
接下来的代码也获取<name>标签,但仅 用狗类型指定的标签。
var myData:XML = <names>
<name type="person">Jack</name>
<name type="dog">Oso</name>
<name type="dog">Sadie</name>
</names>;
for each ( var name:XML in myData..name.(@type= 'dog' ) ) {
trace ( name.toString() );
}
@
语法类似于XPath和XSLT。 它用于指定我们在查看属性而不是XML元素。
E4X是该语言的绝佳补充。 它将XML解析从繁琐的工作变成一种乐趣。 Web服务甚至可以E4X格式返回以便于解析。
结论
Adobe在ActionScript方面取得了非凡的进步。 这种语言比大多数人认为的要复杂得多。 我想您会发现Adobe所做的是从Java的对与错中学到的一些经验教训,并将它们纳入了他们对ActionScript 3语言的开发中。 您会对结果感到非常满意。
想要查询更多的信息
- 有关ActionScript和Java语法之间的相似性的更多信息,请阅读Yakov Fain的文章“比较Java 5和ActionScript 3的语法”(JDJ,2006年11月12日)。
- 可从开放源代码Flash下载Java到ActionScript的转换器,它允许您使用Java而不是ActionScript来创建Flash内容。
- 有关可帮助您在ActionScript,Flex,Java和JavaScript开发之间迁移的资源列表,请参阅RIAdobe的比较列表。
- Flex.org是Adobe Flex所有事物的来源。
actionscript3