首先要习惯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/效果相同,推荐用后者,这样层次更分明
好了,开始定义第一个类:
01
package
{
02
public
class
Human {
03
04
public
function
Human(){
05
this
._name =
"暂无名字"
;
06
trace
(
"Human构造函数被调用!"
);
07
}
08
09
private
var
_name:
String
;
10
public
function
get
Name():
String
{
11
return
_name;
12
}
13
14
////仅本类及子类定义中可用(实际上这个编译能过,但无法在子类中使用)
15
// protected function set Name(n:String):void{
16
// this._name = n;
17
// }
18
19
20
public
function
SetName(n:
String
):
void
{
21
this
._name = n;
22
}
23
24
//属性 set get示例
25
private
var
_sex:
Boolean
26
public
function
set
Sex(v:
Boolean
):
void
{
27
_sex = v;
28
}
29
public
function
get
Sex():
Boolean
{
30
return
_sex;
31
}
32
33
public
function
Hello():
void
{
34
trace
(_name +
" say:Hello World!"
);
35
HiChildren();
//测试在本类中调用受保护方法
36
}
37
38
//受保护方法
39
protected
function
HiChildren():
void
{
40
trace
(_name +
":HiChildren"
);
41
}
42
43
//静态方法
44
public
static
function
WhoAmI():
String
{
45
return
"This is a Human Class"
46
}
47
}
48
}
上面演示了构造器,属性(set/get),静态方法,受保护方法,注意:AS3中不支抽象类
01
package
{
02
public
class
Man
extends
Human {
03
public
function
Man(n:
String
):
void
{
04
super
();
05
SetName(n);
06
super
.Sex=
true
;
07
trace
(
"Man构造函数被调用!"
);
08
HiChildren();
//调用父类的受保护方法
09
}
10
11
//覆盖父类的性别设置函数
12
public
override
function
set
Sex(v:
Boolean
):
void
{
13
//Sex = true;//既然已经是男的,肯定是男的,这里就用不着了,除非咱们的系统支持"变性"
14
trace
(
"无法修改Man的性别"
);
15
}
16
17
18
//protected override function set Name(n:String):void{
19
// //Name = n;//报错:对Name的引用有歧义
20
// }
21
22
23
public
function
ChaseGirls():
void
{
24
trace
(Name +
"正在泡妞..."
);
25
}
26
}
27
}
上面演示了类继承、覆写,下面调用这二个类测试一番:
01
var
h:Human =
new
Human();
02
trace
(h.Name);
03
h.Sex =
true
;
04
trace
(h.Sex);
05
trace
(Human.WhoAmI())
06
h.Hello();
07
//h.Name = "菩提树下的杨过";//这里会报错:属性只读,因为Name的set方法受保护
08
//h.HiChildren(); //同理无法调用
09
10
var
_man:Man =
new
Man(
"菩提树下的杨过"
);
11
_man.Sex =
false
;
12
trace
(
"_man的性别:"
+ _man.Sex);
13
//trace(Man.WhoAmI());//静态方法将不被继承
14
_man.Hello();
15
//_man.HiChildren();//受保护方法无法在子类实例中使用
16
_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再改一下:
01
package
{
02
public
dynamic
class
Human {
03
04
public
function
Human() {
05
trace
(
"Human构造函数被调用!"
);
06
}
07
08
public
function
toString():
String
{
09
return
"This is a Human instance!"
;
10
}
11
}
12
}
注意dynamic关键字,加上这个后,Human就具备了动态修改属性的能力,看下面的测试代码:
01
var
h:Human =
new
Human();
02
h.age =
10
;
03
h.name =
"菩提树下的杨过"
;
04
h.Say =
function
(){
05
trace
(h.name +
":Hello!"
);
06
}
07
trace
(h.toString());
08
trace
(h.age);
09
trace
(h.name);
10
h.Say();
11
12
var
h2:Human =
new
Human();
13
trace
(h2.age);
//输出undefiend
输出结果:
Human构造函数被调用!
This is a Human instance!
10
菩提树下的杨过
菩提树下的杨过:Hello!
Human构造函数被调用!
undefined
如果一个类不想被继承,可以用final关键字标识,通常可以把一些辅助方法以static方式定义在final标识的类中,构成自己的工具类库(有点象c#中的静态类)
01
package
{
02
public
final
class
MyUtils {
03
04
public
static
function
Test(s:
String
):
String
{
05
trace
(s);
06
return
s;
07
}
08
09
public
static
function
Now():
String
{
10
trace
(
new
Date
());
11
return
new
Date
().toLocaleString();
12
}
13
}
14
}
调用:
1
MyUtils.Test(
"hello test"
);
2
MyUtils.Now();
用final + static组合还能实现类似枚举的效果:
1
package
{
2
public
final
class
LOGIN_REG_ERROR {
3
public
static
const
USERNAME_EXISTS =
"用户名已存在"
;
4
public
static
const
PASSWORD_ERROR =
"密码错误"
;
5
public
static
const
USENAME_ERROR =
"用户名错误"
;
6
//...
7
}
8
}
使用示例:
1
var
_loginResult:
String
;
2
if
(_loginResult==LOGIN_REG_ERROR.USERNAME_EXISTS) {
3
trace
(
"用户名已存在!"
);
4
}
AS3.0还支持接口,看下面的代码
1
package
{
2
public
interface
IFly {
3
function
Fly():
void
;
4
}
5
}
01
package
{
02
public
class
Duck
implements
IFly {
03
public
function
Duck() {
04
trace
(
"来来,我是一只鸭子..."
);
05
}
06
07
public
function
Fly():
void
{
08
trace
(
"请叫我小飞侠,谢谢!"
)
09
}
10
}
11
}
最后看下原型链prototype:在javascript中正是得益于prototype才实现了很多惊人的应用,同样在as3.0中也存在原型链,所有动态属性的继承都可以通过原型继承实现,不过要注意的是:如果你准备对一个类进行prototype扩展以实现原型继承,则该类必须标识为dynamic,下面是示例代码:
1
var
d:Duck =
new
Duck();
2
d.Fly();
3
4
Duck.prototype.Swim =
function
(){
5
trace
(
"正在游泳...请回避(裸泳?)"
);
6
}
7
8
d.Swim();
//请先将上一段代码中的Duck类定义加上dynamic关键字,否则本行代码无法执行