ActionScript 3.0 语法
1. 在Flash Builder 4 中的角本文件声明:
<fx:Script>
<![CDATA[
//角本内容
]]>
</fx:Script>
2. 常量和变量
在ActionScript 3.0中使用常量和变量和其他的编程开发语言一样,没什么太大的区别,作用点都是相同的。简单理解就是常量就是值不会改变的量,变量则相反。
在AS3.0中常量也可以分为两种:顶级常量和用户自定义常量。所谓顶级常量就是语言库内部所提供的常量,他们是:
1、Infinity:表示正无穷大
2、-Infinity:表示负无穷大
3、NaN:表示非数字的值
4、undefined:一个适用于尚未初始化的无类型变量或未初始化的动态对象属性的特殊值。
其次便是用户自定义的常量了,通常使用关键字const来定义。
l 变量定义:
语法格式:
<作用域> var <变量名称>:<变量类型>;
程序示例:
//定义一个私有的字符串类型的变量s
private var s:String;
//定义并付默认值:
private var s:String ="测试";
l 常量定义:
//按惯例,常量的名字都应大写。这样能够容易识别和区分属性中的常量。
static public const EXAMPLE:String = "example";
3. 方法定义:
语法格式:
<作用域> function <方法名称>(<参数1>,<参数2>…<参数n>):<方法返回数据类型>{
//方法内容
}
程序示例:
private function sum(mVal1:Number,mVal2:Number):Number{
return mVal1+mVal2;
}
4. 分支和循环语句
l 三元运算符:执行简单的判断运算
三元运算符比较适合简单的判断赋值运算,不适合于根据条件比较结果然后执行大量程序代码的情况,此时应该使用if语句。
语法格式:<表达式>?<表达式成立的返回值>:<表达式不成立的返回值>
程序示例:var result:String; //定义一个字符串变量
var n:int=2;
result = n > 0 ? "大于0":"小于或等于0";
trace(result); //输出结果
l if语句:执行有条件选择性的判断运算
条件语句允许我们做出逻辑判断,满足条件应该做什么?不满足条件又应该做什么?if条件语句则是用得最多的一种,功能也比较多、比较强。与三元运算符相比,不同的是if语句没有结果,if是为了有条件的执行其他语句。
程序示例:var a:String="A"; //取出文本框txtA的值
var b:String="B"; //取出文本框txtB的值
if(a==b){
Alert.show("两个数相等");
}else{
Alert.show("两个数不相等");
}
满足条件执行if后面的程序块,不满足条件则执行else后面的代码块,这是简单的条件判断。如果要使用if来判断更多的条件,可以使用if语句的另一种用法:if--else if---else if.
程序示例:var d:int=int(88);
if(d==0){
Alert.show("你输入的数"+d+"等于0");
}else if(d>0){
Alert.show("你输入的数"+d+"大于0");
}else if(d<0){
Alert.show("你输入的数"+d+"小于0");
}
l switch语句:执行有条件选择性的判断运算
switch语句非常类似于if语句,因为它也是根据条件来选择性的执行某段程序代码块。不同的是switch可以一次将测试值与多个值进行比较判断,而不是只测试一个判断条件,如同if--else if--else if语句一样。
程序示例:var number:int=int(txtE.text);
var result:String;
switch(number){
case 1:
result="星期一";
break;
case 2:
result="星期二";
break;
case 3:
result="星期三";
break;
case 4:
result="星期四";
break;
case 5:
result="星期五";
break;
case 6:
result="星期六";
break;
case 7:
result="星期日";
break;
default:
result="输入错误";
break;
}
Alert.show(result);
l for/for in/for each:执行循环处理
“循环”,就是重复的执行相同的语句。重复执行一定的次数,或者在不满足循环条件后自动终止循环。说到循环语句,相信大家都对他是在熟悉不过了,无外乎就是do、while、for、foreach。在ActionScript 3.0中也是如此。其实只需要弄清不同循环之间的区别和特性就OK了。它们有的适合在循环次数确定的时候使用(如:for循环语句),有的则适合在循环次数不确定的时候使用(如:while语句),而有的无论如何也需要执行一次循环体(如:do--while循环语句)。
程序示例://do--while循环语句
var i:int=10;
var sum:int=0;
do{
sum+=i;
i--;
}while(i!=0);
Alert.show(sum.toString());
//while循环语句
var i:int=10;
var sum:int=0;
while(i!=0){
sum+=i;
i--;
}
Alert.show(sum.toString());
//for循环语句
var sum:int=0;
for(var i:int=1;i<=10;i++){
sum+=i;
}
Alert.show(sum.toString());
除了上面这几种循环语句的使用方式外,在ActionScript 3.0中对于for循环来说还有另外两种使用方式,他们分别是for--in和for each语句。使用都很简单,如下代码示例:
var employee:Object=newObject();
employee.Name="xxxx";
employee.Sex="男";
employee.Email="xxxx@163.com";
employee.Address="中国¡¤西安";
var temp:String="";
for(varemp:Stringinemployee){
temp+=employee[emp]+"n";
}
Alert.show(temp);
下面是for each()循环语句的使用方式:
var books:Array = new Array("IBM","APPLE","SUN","ADOBE");
foreach(vars:Stringinbooks){
Alert.show(s);
}
在ActionScript 3.0中使用循环语句,用样可以使用continue,break来跳出循环,使用上和C#/Java是一样的。
5. 类的基本要素
在ActionScript 3.0中类是最基本的编程结构,所以必须先掌握编写类的基础知识。关于类有基本必须弄清楚的元素,就是所有的类都必须放在扩展名为.as的文件中,每个as文件里只能定义一个public类,且类名要与.as的文件名相同。这一点和Java是完全相同的。
另外,在ActionScript 3.0中,所有的类都必须放在包中。用包来对类进行分类管理,相当于文件系统的目录。包的路径相对于类路径(classpath),默认的类路径就是项目的跟目录,既包含mxml文件的所在目录。在Java中同样有包的概念,而在.NET中大家通常称其为名称空间或命名空间。于之不同的是Java/.NET的类可以不属于任何包(名称空间),ActionScript则必须属于包。
程序示例:
/*
*包:ActionScript.OOP
*/
package ActionScript.OOP
{
/*
*类:属于ActionScript.OOP包
*/
public class Book
{
/*
*构造方法
*/
public function Book()
{
//在开发的路上
}
}
}
6. 类的属性和方法
在ActionScript 3.0中既然有类,那类的成员属性和方法肯定是不会缺少的。属性和方法的定义和C#/Java相差不大,也同样有修饰符(本文后续部分介绍)。说简单点类的属性就是和类关联的变量,通过关键字"var"来声明,类的方法则是类的行为(所谓的能做些什么),与C#/Java不同的是ActionScript 3.0中的方法需要使用"function"关键字来声明。
//定义属性(默认为internal)
var name:String="ActionScript开发手册";
/*
*使用function定义方法
*/
public function GetBookName():String{
return name;
}
这里需要注意一点,属性的定义默认为internal,另外还有如private,public,protected等修饰符可以进行修饰。如果定义为默认的或是private则外部不能访问类的属性,如果定义为public则不能完好的封装类的成员属性,那怎么办那?在ActionScript 3.0里对类的成员属性也提供了getters和setters,如下代码块:
//定义属性(默认为internal)
var name:String="ActionScript开发手册";
public function get name():String{
returnthis.name;
}
public function set name(name:String):void{
this.name=name;
}
类的属性访问器上和C#/java也是有所不同的,形式上和Java很相似,但是还所以一点点的差别,在JavaBean里的成员属性的访问器的get后第一个字母要大写,而在实际的开发中发现,这里随便大小写都是可以的,以我个人开发Java的习惯,在ActionScript中定义属性的getters和setters通常就是照Java的方式来编写。如上name属性的getters在Java里应该是public Stirng getName(){......}。
7. 类的继承
在.NET/Java这两大平台下,关于OO的各种书籍、文章、杂志等数不胜数。OO的三大特性:封装、继承和多态大家都快说破嘴了。当然ActionScript作为一门面向对象的编程语言,也同样具备这些特性,与类密切相关的就是继承。OK,下面我们来看看在ActinScript 3.0中类的继承是怎么实现的。以动物举例说明,定义父类如下:
package ActionScript.OOP.Inheritance
{
import mx.messaging.channels.StreamingAMFChannel;
public class Animal
{
public function Animal()
{
this.name="无名";
}
public function Animal(name:String)
{
this.name=name;
}
private var name:String="";
public function get Name():String{
return this.name;
}
public function set Name(name:String):void{
this.name=name;
}
}
}
然后我们需要写Cat和Dog两个类,Cat和Dog都有名字,那么我门就可以直接继承(ActionScript的继承同Java一样,通过关键字extends继承)Animal使用其内部定义的name就OK,这样就减少了写重复代码。在ActionScript 3.0中,子类从他的父类中继承的成员有方法、属性、事件、索引等,这和C#/Java是完全一样的,但对于构造方法,有有一种特殊的继承,就是构造方法只能被调用。ActionScript调用父类的构造方法同Java一样通过super关键字调用,C#则是通过base调用。下面是Cat和Dog基础于父类Animal的代码:
package ActionScript.OOP.Inheritance
{
public class Cat extends Animal
{
public function Cat()
{
super();
}
}
}
package ActionScript.OOP.Inheritance
{
public class Dog extends Animal
{
public function Dog()
{
super();
}
}
}
8. 方法的覆盖
方法的覆盖也就是要将从父类继承下来的方法重新实现。这里需要注意的是只有父类方法被声明为public或protected的时候在子类中才能通过override去覆盖。
比如这样一个应用场景,公司里普通员工和部门经理的工资问题,部门经理的工资是普通员工的3部,员工的其他属性都是相同的,所以我们在定义部门经理类的时候可以直接继承于普通员工,然后去覆盖(重新实现)计算工资的方法便可。
package ActionScript.OOP.Inheritance
{
public class Employee
{
public function Employee()
{
}
private var salary:Number=0.0;
public function get Salary():Number{
return this.salary;
}
public function set Salary(name:salary):void{
this.salary=salary;
}
public function GetSalary():Number{
return this.salary;
}
}
}
下面是部门经理类的代码:
package ActionScript.OOP.Inheritance
{
/*
*部门经理
*/
public class Manager extends Employee
{
public function Manager()
{
super();
}
/*
*部门经理的工资是普通员工的3部
*/
public override function GetSalary():Number{
return GetSalary()*3;
}
}
}
方法的覆盖就这么简单,只要父类方法被声明为public或protected在子类中就可以进行重新实现,覆盖父类方法的关键字"override"。
9. 动态类
与Java一样,在ActionScript 3.0中提供了动态类(dynamic)。动态类定义在运行时可通过添加或更改属性和方法来改变的对象。非动态类(如 String 类)是密封类。您不能在运行时向密封类中添加属性或方法。在声明类时,可以通过使用 dynamic 属性来创建动态类。
动态类创建好的的程序结构如下代码块:
package ActionScript.OOP.Dynamic
{
/*
* 创建动态类使用dynamic关键字进行声明
*/
public dynamic class Employee
{
public function Employee()
{
}
}
}
之所一叫动态类,就是我们可以在运行的时候给他动态的附加成员,比如我们需要为上面的动态类Employee添加一个Name属性,那应该怎么添加呢?如下代码块:
public function TestEmployee():void {
var employee:Employee = new Employee();
employee.Name = "Beniao";
trace(employee.Name);
}
这里需要注意一点,添加到动态类实例中的属性是运行时实体,因此会在运行时完成所有类型检查。不能向以这种方式添加的属性中添加类型注释。出来可以动态添加属性外,也可以动态添加方法,如下示例代码:
public function TestEmployee():void {
var employee:Employee = new Employee();
employee.GetName() = function {
//方法体略
}
}
但是,以这种方式创建的方法对于 Employee类的任何私有属性或方法都不具有访问权限。而且,即使对 Employee类的公共属性或方法的引用也必须用 this 关键字或类名进行限定。
10. 修饰符
ActionScript 3.0中的常用修饰符主要有internal、private 、public和protected。在定义类或成员属性/方法的时候不加任何修饰符,默认为internal修饰,详细如下:
(1)private:仅当前类可访问,称为私有成员;
(2)internal(默认):包内可见,在同一文件夹下可访问(如果不写权限修饰符,默认权限也是它);
(3)protected:子类可访问,与包无关。如果不是该类的子类,那么 protected 和 private 是一样的;
(4)public:完全公开。任何地方、任何对象都可以访问这个类的成员。
另外还有个特殊的修饰符"static",要定义静态类或是静态成员就使用static关键字来修饰,和C#/Java的用法一样。
11. 抽象类
抽象类又叫抽象基类:可以包含一般类所包含的所有特性,例如,字段,属性,方法,抽象类不能被实例化他主要用在类的定义和部分实现这方面,所以他需要在扩充类中完整的扩充并实现功能.另外抽象类还包含一个很特殊的方法,叫抽象方法(这些方法基本上是没有执行代码的函数,由继承于该类的类重写(override)并提供具体实现).在Java和C#中,有abstract关键字来定义抽象类,而在As3中,并没有提供抽象类的支持,尽管abstract已经属于关键字,我们只可以通过模拟方法来实现抽象类的机制。
如下实例,Adaptee.as就是一个抽象类,而如requestB()则是一个抽象方法。
package {
public class Adaptee {
public function requestA():void {
trace("Adaptee:requestA()");
}
public function requestB() {
}
public function requestC():void {
trace("Adaptee:requestC()");
}
}
}
12. 接口
接口是一种特殊的抽象类,用interface 关键字标记,他可以包含实例/静态方法和getter/setter方法,任何实现该接口的类就必须按照接口的定义实现这些方法.As3中的类可以实现(implements)多个接口.相对于类,接口更象是一种方法的协议,使用接口可以更好的管理模块的功能,方便整理和引用。
代码示例:
/*
定义接口
*/
package {
public interface ITarget {
function renamedRequestA():void;
function requestA():void;
function requestB():void;
}
}
/*
实现接口
*/
package {
public class Target implements ITarget {
public function renamedRequestA():void {
trace("ITarget:renamedRequestA()");
}
public function requestA():void {
trace("ITarget:requestA()");
}
public function requestB():void {
trace("ITarget:requestB()");
}
}
}