第一个自定义类的尝试:
//先新建一个 ActionScript 3.0 工程保存 //然后, 新建 ActionScript 3.0 类, 根据向导随意取类名为 CTest, 自动生成代码如下: package { public class CTest { public function CTest() { //与类同名的方法是构造方法 trace("Hello CTest!"); //这行是手动添加, 修改文件后须先保存再测试运行 } } } //把类文件(CTest.as)保存在和当前工程相同的目录, 然后在工程的时间轴的第一帧的动作中写入: var obj:CTest = new CTest(); //然后测试运行, 会看到测试输出: Hello CTest!
关于包名与类名:
//上面创建的 CTest 类属于一个包(package), 包的名称用来指示文件路径; 上面的匿名包指示文件和 *.fla 在相同目录 //如果要把 CTest.as 保存在工程目录下的 AAA\BBB\, 则包名应该是 AAA.BBB; 推断: 如果某个目录下有多个 *.as 文件, 其中的包名必须是一致的 /* AAA\BBB\CTest.as */ package AAA.BBB { public class CTest { public function Method1() { trace("Method1"); } public function Method2() { trace("Method2"); } } } /* fla 中关键帧中的代码 */ import AAA.BBB.CTest; //在输入代码时, 这行会自动加入; 可用 import AAA.BBB.*; 导入目录下的所有包 var obj:CTest = new CTest(); //也可写作 var obj:AAA.BBB.CTest = new AAA.BBB.CTest(); 但如果没有命名冲突就没必要了 obj.Method1(); obj.Method2(); //每个包中只能有一个类, 这个类的名称必须与文件名相同; 文件中可以有其它辅助类, 但必须放在包外. //一个源文件中也许会没有包、没有类, 只有一些常量或变量. //包还可以嵌套, 如官方提供的 flash.display 包就属于 flash 包; 不过自己写程序应该用不着嵌套包.
类与类成员的可见性:
/* 类的可见性: */ dynamic //动态类, 可在运行时向实例添加成员 final //密封类, 不能被继承 internal //包内可见(默认) public //包内外可见(常用) /* 类成员可见性: */ internal //包中可见(默认) private //类中可见 protected //类及派生类中可见 public //类内外、包内外都可见 static //静态成员; 属于该类但不属于该类的实例 UserDefinedNamespace //使用自定义的命名空间指定可见性
静态成员与实例成员:
//类的静态成员通过类名调用, 类的实例成员通过实例化后的对象调用 //--------------------------------- package { public class CTest { public static var fCount:int = 0; //静态变量 public static const PI = 3.14; //静态常量 public static function Method1() { trace("Method1"); } //静态方法 public function Method2() { trace("Method2"); } //实例方法 } } //--------------------------------- CTest.fCount = 123; trace(CTest.fCount); trace(CTest["fCount"]); trace(CTest.PI); trace(CTest["PI"]); CTest.Method1(); CTest["Method1"](); var obj:CTest = new CTest(); obj.Method2(); obj["Method2"](); //AS3 还允许静态方法与实例方法同名, 但没理由这样用.
关于构造函数:
//AS3 中的类只能有一个构造函数, 因其可见性必须是公开的所以可以省略 public, 构造函数不能有返回值. //如果不定义, 系统将使用无参的默认构造函数 //--------------------------------- package { public class CTest { public var fStr:String; public function CTest(str:String) { fStr = str; } } } //--------------------------------- var obj:CTest = new CTest("ABC"); trace(obj.fStr);
使用属性:
//--------------------------------- package { public class CTest { private var fCount:int = 0; public function get Count():int { return fCount; } public function set Count(aCount:int) { fCount = (aCount > 0) ? aCount : 0; } } } //--------------------------------- var obj:CTest = new CTest(); obj.Count = 99; trace(obj.Count); //99 obj.Count = -1; trace(obj.Count); //0
绑定方法(输入或输出的方法)测试:
//--------------------------------- package { public class CTest { private function Method1() { trace(this); } public function Method2():Function { return Method1; } public function Method3(aFun:Function) { aFun(); } } } //--------------------------------- function myFunc1() { trace(this); } myFunc1(); //[object MainTimeline] var obj:CTest = new CTest(); var myFunc2:Function = obj.Method2(); myFunc2(); //[object CTest] obj.Method3(myFunc2); //[object CTest]
使用类模拟枚举:
//这种类一般不需要继承(final), 成员也应该是静态常量(static const) //--------------------------------- package { public final class CTest { public static const MALE:String = "male"; public static const FEMALE:String = "female"; } } //--------------------------------- var age:String; age = "female"; //age = "male"; switch (age) { case CTest.MALE: trace("Male"); break; case CTest.FEMALE: trace("Female"); break; default: trace("?"); }
AS3 的命名空间:
//AS3 的 "包" 的作用类似于其他语言的 "命名空间", 但它实际指示的是相对路径 //AS3 的 "命名空间" 只是控制类成员的可见性, 其作用类似于 public、private、protected、internal //感觉设计的不好, 尽量不使用它
动态(dynamic)类:
//动态类的实例可以动态地添加成员 //--------------------------------- package { public dynamic class CTest { public const Name = "CTest"; } } //--------------------------------- var obj:CTest = new CTest(); trace(obj.Name); //CTest obj.A = 123; trace(obj.A); //123 obj.B = function () { trace("CTest B"); }; obj.B(); //CTest B function myFunc() { trace("myFunc"); } obj.C = myFunc; obj.C(); //myFunc
prototype:
//--------------------------------- package { public dynamic class CTest { public const Name = "CTest"; } } //--------------------------------- CTest.prototype.A = 123; CTest.prototype.B = function () { trace("CTest B"); }; //function myFunc() { trace("myFunc"); } //CTest.prototype = myFunc; var obj:CTest = new CTest(); trace(obj.Name); //CTest trace(obj.A); //123 obj.B(); //CTest B //obj.C(); //
类继承:
//基类, 保存在工程目录下 CBase.as package { public class CBase { public function BaseMethod() { trace("BaseMethod"); } } } //子类, 保存在工程目录下 CTest.as package { public class CTest extends CBase { //继承关键字 extends public function TestMethod() { trace("TestMethod"); } } } //测试 var obj:CTest = new CTest(); obj.BaseMethod(); //BaseMethod obj.TestMethod(); //TestMethod
从接口继承:
//AS3 不支持抽象类, 但支持接口 //接口只能使用 public 和 internal 访问控制说明符 //接口不能包含变量或常量,但是可以包含属性 //继承接口的方法时,方法格式须一致, 但参数名和参数的默认值可不同 //继承多个接口时可用逗号隔开 //接口, 保存在工程目录下 IBase.as package { public interface IBase { function InterfaceMethod(); //接口成员不使用可见性修饰, 都是公开的 } } //子类, 保存在工程目录下 CTest.as package { public class CTest implements IBase { public function InterfaceMethod() { trace("InterfaceMethod"); } public function TestMethod() { trace("TestMethod"); } } } //测试 var obj:CTest = new CTest(); obj.InterfaceMethod(); //InterfaceMethod obj.TestMethod(); //TestMethod
同时同类和接口继承:
//接口, 保存在工程目录下 IBase.as package { public interface IBase { function InterfaceMethod(); //接口成员不使用可见性修饰, 都是公开的 } } //基类, 保存在工程目录下 CBase.as package { public class CBase { public function BaseMethod() { trace("BaseMethod"); } } } //子类, 保存在工程目录下 CTest.as package { public class CTest implements IBase { public function InterfaceMethod() { trace("InterfaceMethod"); } public function TestMethod() { trace("TestMethod"); } } } //测试 var obj:CTest = new CTest(); obj.InterfaceMethod(); //InterfaceMethod obj.BaseMethod(); //BaseMethod obj.TestMethod(); //TestMethod var i:IBase = new CTest(); i.InterfaceMethod(); //InterfaceMethod var base:CBase = new CTest(); base.BaseMethod(); //BaseMethod
覆盖(override):
//CBase.as package { public class CBase { public function Method() { trace("BaseMethod"); } } } //CTest.as package { public class CTest extends CBase { override public function Method() { trace("TestMethod"); } } } //测试 var base:CBase = new CTest(); base.Method(); //TestMethod //只有实例方法可以被覆盖, 须格式相同, 访问级别相同 //静态方法不能被覆盖, 也不会被继承 //final 方法可禁止覆盖
在子类中使用父类:
//CBase.as package { public class CBase { public function BaseMethod() { trace("BaseMethod"); } } } //CTest.as package { public class CTest extends CBase { public function TestMethod() { super.BaseMethod(); //关键字 super trace("TestMethod"); } } } //测试 var obj:CTest = new CTest(); obj.TestMethod(); //BaseMethod/TestMethod
属性的继承与覆盖:
//CBase.as package { public class CBase { private var fNum1:int; private var fNum2:int; public function get Num1():int { return fNum1; } public function set Num1(num:int) { fNum1 = num; } public function get Num2():int { return fNum2; } public function set Num2(num:int) { fNum2 = num; } } } //CTest.as package { public class CTest extends CBase { private var fNum2:int; override public function get Num2():int { return fNum2; } override public function set Num2(num:int) { fNum2 = (num > 0) ? num : 0; } } } //测试 var obj:CTest = new CTest(); obj.Num1 = 123; trace(obj.Num1); //123 var base:CBase = new CTest(); base.Num1 = -1; trace(base.Num1); //-1 base.Num2 = -1; trace(base.Num2); //0