首先要习惯AS3.0的几个BT约定:
1.一个.as文件中,只能定义一个类
2.类名称必须与.as的文件名相同
3.类定义中必须要有package包声明
4.一个类最多只能有一个构造函数
5.包package的路径/名称约定:
这个初次接触时感觉有点小复杂,这样描述吧:
如果您在定义一个类时,package的声明指定了名称,比如 package jimmy{ public class MyClass{...}},那么也就意味着需要对它引用的fla/as文件同级目录下,必须要有jimmy目录,而且jimmy目录下必须要有MyClass.as文件,而且MyClass文件中定义的类名必须为MyClass
然后你再引用该类时,必须导入该包
import jimmy.MyClass;
然后才能引用比如: var mycls:MyClass = new MyClass();
简单来讲,就是package名必须与目录名准确匹配。
这里还有一种特殊情况:
假如定义的package名称为jimmy.yang,根据上面的解释,则同级目录下必须要有jimmy.yang目录,这是没问题的,但是还可以这样组织目录结构,先创建一个jimmy目录,然后再创建一个yang目录,然后把as文件放到jimmy/yang/目录下,即:如果package名称中有"点"时(比如package a.b),则目录./a.b/ 与./a/b/效果相同,推荐用后者,这样层次更分明
好了,开始定义第一个类:
package { public class Human { public function Human(){ this._name = "暂无名字"; trace("Human构造函数被调用!"); } private var _name:String; public function get Name():String{ return _name; } ////仅本类及子类定义中可用(实际上这个编译能过,但无法在子类中使用) // protected function set Name(n:String):void{ // this._name = n; // } public function SetName(n:String):void{ this._name = n; } //属性 set get示例 private var _sex:Boolean public function set Sex(v:Boolean):void{ _sex = v; } public function get Sex():Boolean{ return _sex; } public function Hello():void{ trace(_name + " say:Hello World!"); HiChildren();//测试在本类中调用受保护方法 } //受保护方法 protected function HiChildren():void{ trace(_name + ":HiChildren"); } //静态方法 public static function WhoAmI():String{ return "This is a Human Class" } } }
上面演示了构造器,属性(set/get),静态方法,受保护方法,注意:AS3中不支抽象类
package { public class Man extends Human { public function Man(n:String):void { super(); SetName(n); super.Sex=true; trace("Man构造函数被调用!"); HiChildren();//调用父类的受保护方法 } //覆盖父类的性别设置函数 public override function set Sex(v:Boolean):void { //Sex = true;//既然已经是男的,肯定是男的,这里就用不着了,除非咱们的系统支持"变性" trace("无法修改Man的性别"); } //protected override function set Name(n:String):void{ // //Name = n;//报错:对Name的引用有歧义 // } public function ChaseGirls():void{ trace(Name + "正在泡妞..."); } } }
上面演示了类继承、覆写,下面调用这二个类测试一番:
var h:Human = new Human(); trace(h.Name); h.Sex = true; trace(h.Sex); trace(Human.WhoAmI()) h.Hello(); //h.Name = "菩提树下的杨过";//这里会报错:属性只读,因为Name的set方法受保护 //h.HiChildren(); //同理无法调用 var _man:Man = new Man("菩提树下的杨过"); _man.Sex = false; trace("_man的性别:" + _man.Sex); //trace(Man.WhoAmI());//静态方法将不被继承 _man.Hello(); //_man.HiChildren();//受保护方法无法在子类实例中使用 _man.ChaseGirls();
输出结果:
Human构造函数被调用!
暂无名字
true
This is a Human Class
暂无名字 say:Hello World!
暂无名字:HiChildren
Human构造函数被调用!
Man构造函数被调用!
菩提树下的杨过:HiChildren
无法修改Man的性别
_man的性别:true
菩提树下的杨过 say:Hello World!
菩提树下的杨过:HiChildren
菩提树下的杨过正在泡妞...
另外:做为符合ECMA规范的语言,ActionScript同样具有类似JavaScript的动态语言能力,我们把Human.cs再改一下:
package { public dynamic class Human { public function Human() { trace("Human构造函数被调用!"); } public function toString():String { return "This is a Human instance!"; } } }
注意dynamic关键字,加上这个后,Human就具备了动态修改属性的能力,看下面的测试代码:
var h:Human = new Human(); h.age = 10; h.name = "菩提树下的杨过"; h.Say = function(){ trace(h.name + ":Hello!" ); } trace(h.toString()); trace(h.age); trace(h.name); h.Say(); var h2:Human = new Human(); trace(h2.age);//输出undefiend
输出结果:
Human构造函数被调用!
This is a Human instance!
10
菩提树下的杨过
菩提树下的杨过:Hello!
Human构造函数被调用!
undefined
如果一个类不想被继承,可以用final关键字标识,通常可以把一些辅助方法以static方式定义在final标识的类中,构成自己的工具类库(有点象c#中的静态类)
package { public final class MyUtils { public static function Test(s:String):String { trace(s); return s; } public static function Now():String { trace(new Date()); return new Date().toLocaleString(); } } }
调用:
MyUtils.Test("hello test"); MyUtils.Now();
用final + static组合还能实现类似枚举的效果:
package { public final class LOGIN_REG_ERROR { public static const USERNAME_EXISTS = "用户名已存在"; public static const PASSWORD_ERROR = "密码错误"; public static const USENAME_ERROR = "用户名错误"; //... } }
使用示例:
var _loginResult:String; if (_loginResult==LOGIN_REG_ERROR.USERNAME_EXISTS) { trace("用户名已存在!"); }
AS3.0还支持接口,看下面的代码
package { public interface IFly { function Fly():void; } }
package { public class Duck implements IFly { public function Duck() { trace("来来,我是一只鸭子..."); } public function Fly():void{ trace("请叫我小飞侠,谢谢!") } } }
最后看下原型链prototype:在javascript中正是得益于prototype才实现了很多惊人的应用,同样在as3.0中也存在原型链,所有动态属性的继承都可以通过原型继承实现,不过要注意的是:如果你准备对一个类进行prototype扩展以实现原型继承,则该类必须标识为dynamic,下面是示例代码:
var d:Duck = new Duck(); d.Fly(); Duck.prototype.Swim = function(){ trace("正在游泳...请回避(裸泳?)"); } d.Swim(); //请先将上一段代码中的Duck类定义加上dynamic关键字,否则本行代码无法执行