特色
相对于as2
- 异常反馈
- 运行时进行类型检查
- 支持密封类,无法在运行时动态添加属性方法
- 闭包方法,使得this可以绑定原始实例
- xml成为as3内建数据类型
- 加入正则表达式
- 加入xml语言中类似的命名空间
- 新数据类型(int …)
书写位置
关键帧
外部类文件
2.1 编写fla文件
2.2 编写与fla同名 as 类文件
package { import flash.display.MovieClip; public class as3 extends MovieClip { // 构造器函数 as3文件名、类名、构造函数名必选一致 public function as3() { trace("你好"); } } }
2.3 fla类关联as
2.4 如果as与fla不在同一级配置as路径
数据
所有数据都是对象,所有类继承于Object类
基元数据类型
- Boolean(true|false)
- int 整数
- Number 浮点
//浮点bug
var a:Number=0;
for(var i=0; i<10;i++){
a+=0.1;
}
trace(a);// 0.9999999999999999
- String
- unint 大整数(16位颜色值…)
复杂数据类型
- Array(可由数字或字符串构成)
var arr:Array = [1,2,3];
var arr:Array = new Array(1,2,3);
- Date
- Error
- Function
- RegExp
- XML
- XMLList
- 自定义类
var obj1:Object = new Object();
obj1.name = "mike";
var obj2:Object = {name:"mike"};
- MovieClip:影片剪辑元件
- TextField:动态文本字段或输入文本字段
- SimpleButton:按钮元件
变量声明
在使用变量前必须声明,且使用时赋值必须符合声明类型
var xxx:int = 123;
var xxx:*;//任意类型
var arr1:Array = new Array(1,2,3);
var arr2:Array = arr1;// 引用
arr2[2] = 4;
trace(arr1[2]);//4
常量声明
只读的变量
const a:int = 100;
// 引用常量只能保证引用地址不变,无法保证内容不变
const arr:Array = [1,2];
var arr2:Array = arr;
arr2[1] = 100;
trace(arr[1]);//100
运算符与表达式
和js一样 参见js教程
特殊运算符
运算符 | 实例 |
---|---|
is | 9 is Number//9是number类型 返回true/false |
as | 9 as Number//9是number类型 是返回对象值否则返回null |
in | 2 in Array;‘name’ in Object;//2是否是数组索引或键 |
条件判断
和js一样 参见js教程
循环
for(var key in arr)// 遍历键
for each(var val in arr)// 遍历值
函数
函数声明
// 此定义 this绑定函数域
function 函数名(参数:类型):返回值类型{
函数体;
}
// 函数表达式声明 this会随函数附着的对象改变
var handle:Function=function(a:int, b:int):int {
函数体;
}
handle();
函数参数
- 传值传参
function handle(a:int, b:Array):void{
a = 100;// 基元数据类型拷贝副本传值
b[0] = 100;// 复杂数据类型传参,指向同一块内存
}
var a:int = 5;
var b:Array = new Array(1,2,3);
handle(a,b);
trace(b);// 100,2,3
- 默认参数值
function handle(a:int=3, b:int=2):void{
}
- arguments、callee
function handle(a:int=3, b:int=2):void{
trace('函数参数数组长度: ' + arguments.length);// 长度=调用函数时传递参数
arguments.callee(1,2);// 调用自身
}
- 剩余参数
function handle(a:String, ...params):void {
trace('参数长度'+params.length);// 不包括参数a
}
handle("hello world"1,[1,2,3],{name:'mike'});
函数是Function对象
- function 声明 得函数类型是MethodClosure
- 函数表达式声明 得函数类型是Function-1 依次类推 -2 -3…
import flash.utils.getQualifiedClassName;
var handle:Function = function(){
trace("hello");
}
var handle1:Function = function(){
trace("hello");
}
trace(getQualifiedClassName(handle1));
//trace(getQualifiedSuperclassName(handle));
trace(handle is Function);
trace(handle is Object);
/*function handle(){
trace("hello");
}*/
面向对象
所有类继承于Object类
类与对象
- 新建as3 类文件 hello.as
- 文件名==包内类名==包内类构造函数名
package {
public class hello(){
public var wen:String = "world";
public function hello(){
}
public function sayHello():void{
trace("hello")
}
}
}
类创建与使用
- 创建hello.as
package {
public class hello(){
public var wen:String = "world";
public function hello(){
}
public function sayHello():void{
trace("hello")
}
}
}
- 创建diaoyong.as
package {
import hello;
import flash.display.MovieClip;
public class d15 extends MovieClip{
public function d15(){
var obj:hello = new hello();
trace(obj.wen);
}
}
}
- 创建diaoyong.fla 绑定类diaoyong
- ctrl+F9 运行输出world
hello.as diaoyong.fla diaoyong.as 默认都在同一级目录 不在否则需要配置寻找路径 具体操作如下
类与包
- 类 大写开头 Person
- 包 小写开头 package
- 文件目录结构
--- 未命名-1.fla
--- shuchu.as
--- diaoyong.fla
--- nihao
------ zifu.as
-
fla发布绑定 class shuchu
-
nihao.as
package nihao{
public class zifu{
public var wen:String = "hello";
public function zifu(){
}
}
}
- shuchu.as
package
{// 根目录下
import flash.display.Sprite;// 基类 继承MovieClip类 但没有时间轴
import nihao.zifu;
public class shuchu extends Sprite
{
public function shuchu()
{
var obj:zifu = new zifu ;
trace(obj.wen);
}
}
}
实例属性方法
- d17.as 编写类
package{
import flash.display.Sprite;
public class d17 extends Sprite{
public var wen:String = "hello";
public function shuchu(neirong:String):void{
trace(neirong);
}
}
}
- d17.fla 动作编写调用 但fla发布不绑定任何类
import d17;// d17.fla与d17.as 同级目录
var foo:d17 = new d17();
trace(foo.wen);
// 调用实例方法
foo.shuchu("abc");
静态属性方法
static 关键词
静态不依赖于实例与类绑定 即可获取调用
- 编写d18.as 类文件
package{
import flash.display.Sprite;
public class d18 extends Sprite{
public static var wen:String = "hello";
public static function shuchu(neirong:String):void{
trace(neirong);
}
}
}
- d18.fla
import d18;
trace(d18.wen);
trace(d18.shuchu("hello"));
构造函数
构造器函数没有任何返回值
- 编写类 d19.as
package
{
import flash.display.Sprite;
public class d19 extends Sprite
{
public function d19():void
{
trace("hello");
}
}
}
- 创建d19.fla 动作脚本内 new 类 默认调用构造函数
import d19;
(new d19());
动态类与密封类
dymanic
动态类在运行时可以加入方法、属性 性能没密封类好,代码类型检查宽松不便于维护。
- d20.as 编写动态类
package{
public dynamic class d20{
public var wen:String = "hello";
public function shuchu(neirong:String):void{
trace(neirong);
}
}
}
- d20.fla new 动态类并加入动态属性
var obj:d20 = new d20();
obj.newAttr = 123;
trace(obj.newAttr);
方法重载
方法名相同但根据参数与返回值进行区分不同方法
- d21.as 创建类 实现方法重载
package
{
import flash.display.Sprite;
public class d21 extends Sprite
{
public function sayHi(... foo):*
{
if (foo.length == 1)
{
trace('a');
}
else if (foo.length == 2)
{
trace('b');
}
}
}
}
- d21.fla 创建类实例并调用重载方法
var aoo:d21 = new d21();
aoo.sayHi(12);
对外不可见 故没有public等访问修饰符
- d22.as 创建包外类
package{
import flash.display.Sprite;
public class d22 extends Sprite{
public function d22():void{
var foo:say = new say();
}
}
}
class say{
public function say(){
trace("a");
}
}
- d22.fla new 包类 调用构造函数 构造函数调用包外内
var boo:d22 = new d22();
封装与包操作
隐藏实现,只暴露接口
导入包创建textField文本框并显示hello
- 创建d24.as 导入文本包与显示包
package
{
import flash.display.Sprite;
import flash.text.TextField;
public class d24 extends Sprite
{
public function d24():void
{
var foo:TextField = new TextField ;
foo.text = "hello";
// 添加到显示列表
addChild(foo);
}
}
}
- 创建d24.fla 绑定d24文档类
- 发布运行
类成员访问控制
控制符 | 范围 |
---|---|
public | 包外 |
private | 同一包内 |
protected | 继承类可访问 |
internal | 系统默认访问控制符 |
Getter与Setter
既保护了私有属性,由可以访问私有属性
- 创建d26.as 创建类
package{
public class d26{
private var wen:String = 'a';
public function get wenben():String{
return wen;
}
public function set wenben(ns:String){
wen = ns;
}
}
}
- 创建d26.fla 获取并赋值私有属性
import d26;
var obj:d26 = new d26();
trace(obj.wenben);
obj.wenben = "b";
trace(obj.wenben);
命名空间
避免命名冲突,提升封装性。
命名空间 不能用于类(类只能使用internal或public)
- 定义
命名空间 static 属性:数据类型
命名空间 方法(参数):返回值类型
- 引用
use namespace 命名空间// 开放命名空间作用域 可以直接调用无需再书写命名空间::方法 但是无法关闭
命名限定符::
对象.命名空间::实例属性
- 本质
命名空间是由namespace类实现
不同位置定义命名空间namespace内产生的uri结构
- 案例
d27.as
d27_1.aspackage{ public namespace d27; }
d27_zone.aspackage{ public namespace d27_1; }
d27_diao.aspackage{ import d27; import d27_1; // 打开命名空间 use namespace d27; use namespace d27_1; import flash.display.Sprite; public class d27_zone extends Sprite{ d27 function da():void{ trace("da27 a"); } d27_1 function da():void{ trace("d27_1 a"); } } }
d27.fla 绑定 d27_diao 类package { import d27_zone; import d27; import d27_1; import flash.display.Sprite; public class d27_diao extends Sprite{ public function d27_diao(){ use namespace d27; var foo:d27_zone = new d27_zone(); foo.da(); } } }
复合(聚合)类
当前类中实例化其他类,比如文档类就需要实例化各种需要的组件类
package{
import flash.display.MovieClip;
import flash.display.Shape;
import flash.display.Sprite;
public class d31{
public function d31(){
init();
}
public function init():void{
var a:MovieClip = new MovieClip();
var b:Sprite = new Sprite();
var c:Shape = new Shape();
}
}
}
继承
- 编写 d32.as
package{
import flash.display.Sprite;
public class d32 extends Sprite{
public function d32():void{
graphics.beginFill(0x00ff00);
graphics.drawRect(0,0,100,100);
graphics.endFill();
}
}
}
- 编写文档类 d32_main.as 用于显示
package{
import flash.display.Sprite;
// 同一层无需import 类
public class d32_main extends Sprite{
public function d32_main(){
var obj:d32 = new d32();
addChild(obj);
}
}
}
- 将d32.fla绑定类d32_main
- 发布运行
静态成员伪继承
// 必须在子类将静态成员拷贝一份,
//外部才能调用子类时访问到父类的静态方法
// 否则,只能在子类内部调用静态成员,不能在类外调用父类静态成员
- 创建d33.as
package{
import flash.display.Sprite;
public class d33 extends Sprite{
public function d33(){
//trace(Sub.num);// error
var obj:Sub = new Sub();//10;
trace(Sub.num);//10
trace(Sub.sayHi());//hi
}
}
}
class Main{
static const num = 10;
static function sayHi():void{
trace('hi');
}
}
class Sub extends Main{
static const num = Main.num;
// 必须在子类将静态成员拷贝一份,
//外部才能调用子类时访问到父类的静态方法
static const sayHi = Main.sayHi;
public function Sub(){
//trace(Main.num);// 10
}
}
- 创建d33.fla 绑定d33
继承与访问控制
控制符 | 范围 |
---|---|
public | 包外、包内类、包外类可访问 |
internal | 包内类间可访问 |
private | 类内可访问 |
protected | 子类可访问 |
继承重写(override)
重写方法的访问权限只能相等或更高(protected、public)、方法命名、方法参数、返回值类型必须相同。
- 编写主类 d35_main.as
package{
import flash.display.Sprite;
class d35_main extends Sprite{
public function foo(num:int):void{
trace(num);
}
}
}
- 编写 d35.as 继承重写d35_Main主类
package{
public class d35 extends d35_main{
public function d35(){
foo(13);
}
override public function foo(num:int):void{
trace("重写"+num);
}
}
}
- 编写文档类 d35.fla 绑定 d35.as
继承与super
super不能再静态成员使用
public class Main(){
public function Main(){
trace('主类构造函数');
}
}
public class Sub extends Main{
public function Main(){
super();// 调用父类Main构造方法
}
}
终止类继承与方法重写
可以提高运行效率
public final class/function
多态
同一个接口,使用不同实例调用不同方法
-
里氏替换原则
能够使用父类的地方一定可以使用子类代替 -
向上转换
[d40.as 创建文档类]
向上转换句: private function hua(target:d40_shape):void{// 使用父类类型 向上转换package { import flash.display.Sprite; import flash.display.Stage;// 导入舞台类 public class d40 extends Sprite { private var X:int = 50; private var Y:int = 50; public function d40(){ hua(new d40_rect(this)); hua(new d40_circle(this)); } private function hua(target:d40_shape):void{// 使用父类类型 向上转换 target.fill(); target.move(X,Y); X *= 2; Y *= 2; } } }
[d40_shape.as 创建图像公共基类]
package { import flash.display.Shape; import flash.display.DisplayObjectContainer;//所有对象基类 public class d40_shape { protected var _shape:Shape; public function d40_shape(parent:DisplayObjectContainer){ _shape = new Shape(); parent.addChild(_shape); } protected function draw():void{ // 子类重写 } public function fill():void{ _shape.graphics.beginFill(0x00ff00); draw(); _shape.graphics.endFill(); } // 放置位置 public function move(X:Number,Y:Number):void{ _shape.x = X; _shape.y = Y; } } }
[d40_circle.as 创建shape类的圆形子类 重写draw方法]
package { import flash.display.DisplayObjectContainer; public class d40_circle extends d40_shape { public function d40_circle(parent:DisplayObjectContainer){ super(parent); } override protected function draw():void{ _shape.graphics.drawCircle(0,0,50); } } }
[d40_rect.as 创建shape类的方形子类 重写draw方法]
package { import flash.display.DisplayObjectContainer; public class d40_rect extends d40_shape { public function d40_rect(parent:DisplayObjectContainer){ super(parent); } override protected function draw():void{ _shape.graphics.drawRect(0,0,50,50); } } }
[d40.fla 绑定文档类 d40]
-
向下转换
场景: 子类都向上转换当作父类使用,但可能后面需要区分子类的具体类型就需要向下转换
【转换方法】1. 显示转换String(Obj) 2.隐式转换 (Obj as String)
【创建文档类 d42.as】package{ import flash.display.Sprite; public class d42 extends Sprite { public function d42(){ setter(new d42_son()); } public function setter(obj:d42_father):void{ (obj as d42_son).see(); } } }
[创建父类 d42_father.as]
package { public class d42_father { public function look():void { trace('父类 look'); } } }
[创建子类 d42_father.as]
package{ public class d42_son extends d42_father { override public function look():void{ trace('子类 look'); } public function see():void{ trace('子类 see'); } } }
[创建文档 d42.fla 绑定d42类]
抽象类
as 没有专门的抽象类关键词,只有具有抽象类思想的应用比如 DisplayObject 就是抽离Sprite 与 MovieClip公共属性方法的抽象类。
接口
提炼公共方法但不实现
是数据结构向上转换的核心
依赖倒转原则:多使用接口、抽象类规划,具体类实现使用继承接口抽象类。
接口定义
大写I大头文件名
接口使用
- 类实现的接口方法必须为public
- 可以继承多个接口
- 接口可作为数据类型 即可向上也可向下转换
【创建接口 I45.as】
package{
public interface I45{
function a(num:int):void;
}
}
【实现接口 Id45.as】
package{
public class Id45 implements I45{
public function Id45(){
a(45);
}
public function a(num:int):void{
trace('接口实现输出数字'+num);
}
public function b(num:int):void{
trace('子类独有方法'+num);
}
}
}
【应用接口创建 d45.as】
package{
import flash.display.Sprite;
public class d45 extends Sprite{
public function d45(){
var obj:I45 = new Id45();
obj.a(10);
(obj as Id45).b(10);// 向下转换调用子类独有方法
}
}
}
【绑定接口到fla 创建d45.fla 绑定类为d45】
接口继承
public iterface Ison extends IFather1,IFather2
{
}
接口类型
- 多方法接口: 接口内有多个方法定义
- 单方法接口: 接口内只有一个方法定义,主要用于只对外暴露一个方法的场景y
- 标识接口: 接口内为空,主要是同意其他类使得多个类再数据类型上统一到一个数据接口类型下
事件
采用dom3事件模型: 事件目标与发送事件者脱离耦合性,关联弱。
dom3执行流程:
- 注册监听器,监听某一事件
- 发送事件,事件发生时,执行某一事件(事件传递)
- 监听事件,对某一事件响应处理
- 移除监听器,回收资源
Event类
Event类继承于Object类
type属性
m1.addEventListener(MouseEvent.CLICK,an);
function an(evt:Event):void
{
trace(evt.type);
}
target属性(事件发送者)
可以获取事件发送对象所有属性
m1.addEventListener(MouseEvent.CLICK,an);
function an(evt:Event):void
{
trace(evt.target);
evt.target.x+=100;// 点击右移动100
}
EventDispatcher
addEventListener(事件,处理函数)
removeEventListener(事件,处理函数)
继承于EventDispatcher
自定义事件
【创建事件对象 d51_event.as】
package{
import flash.events.Event;
public class d51_event extends Event{
// 定义静态常量
public static const FA_SHENG:String = '发送一个事件';
private var a:int;// 自定义属性
public function d51_event(){
super(FA_SHENG);// 调用Event构造函数注册事件
}
// 封装属性a
public function get abc():int{
return a;
}
public function set abc(n:int):void{
a = n;
}
// 重写2方法
override public function toString():String{
//"type","bubbles","cancelable","eventPhase" 默认参数
return formatToString("d51_event","type","bubbles","cancelable","eventPhase","abc");
}
override public function clone():Event{
// 复制一个事件对象
var evt:d51_event = new d51_event();
evt.a = a;
return evt;
}
}
}
[创建发送事件类 d51_setEventObject.as]
package{
import flash.events.EventDispatcher;// 发送事件类
public class d51_setEventObject extends EventDispatcher
{
// 手动触发封装
public function chufa():void{
var myEvent:d51_event = new d51_event();
myEvent.abc = 45;
dispatchEvent(myEvent);
}
}
}
[文档类 d51.as]
package{
import flash.display.Sprite;
public class d51 extends Sprite{
public function d51(){
var tt:d51_setEventObject = new d51_setEventObject();
tt.addEventListener(d51_event.FA_SHENG, an);
tt.chufa();
}
private function an(evt:d51_event):void{
trace(evt);
}
}
}
[创建d51.fla文档 绑定d51类]
[d51_event type="发送一个事件" bubbles=false cancelable=false eventPhase=2 abc=45]
自定义发送事件方法
继承EventDispatcher
package{
import flash.events.EventDispatcher;
public class d52 extends EventDispatcher{
// 如果d52 继承 MovieClip 不能多继承EventDispatcher,但MovieClip 继承于DisplayObject,DisplayObject继承于EventDispatcher,所以继承MovieClip 即可继承EventDispatcher
}
}
聚合
package{
import flash.events.Event;
import flash.events.EventDispatcher;
public class MyEventObject{
private var abc:EventDispatcher;
public function MyEventObject(){
abc = new EventDispatcher();
}
public function getDispather():EventDispatcher{
return abc;
}
// 手动触发
public function doevent():void{
abc.dispatchEvent(new Event());
}
}
}
接口
实现IEventDispatcher
package{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
public class MyEventObject implement IEventDispatcher{
private var abc:EventDispatcher;
public function MyEventObject(){
abc = new EventDispatcher();
}
// 重写所有IEventDispatcher方法
// 注册监听器
public function addEventListener(type:String,listener:Function,
useCapture:Boolean=false,priority:int=0,useWeekReference:Boolean=false):void
{
abc.addEventListener(type,listener,useCapture,priority,useWeekReference);
}
// 派发事件
public function dispatchEvent(evt:Event):void{
return abc.dispatchEvent(evt);
}
}
}
事件流
- 3阶段
捕获(外层->内层深入)、目标(找到事件发送目标)、冒泡(内->外)
flash.events.eventPhase 事件流当前阶段
查看事件本身是否支持冒泡 flash.events.bubbles 设为true或false 是否需要冒泡
package{
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.events.Event;
public class d53 extends Sprite{
public function d53(){
var a:Sprite = new Sprite();
draw(a,25,25,0xff0000,50,50);
a.name = "内";
var b:Sprite = new Sprite();
draw(b,12,12,0x00ff00,76,76);// 左上角坐标(x,y)
a.name = "中";
var c:Sprite = new Sprite();
draw(c,0,0,0x0000ff,100,100);
a.name = "外";
addChild(c);
c.addChild(b);
b.addChild(a);
a.addEventListener(MouseEvent.CLICK,look);
b.addEventListener(MouseEvent.CLICK,look);
c.addEventListener(MouseEvent.CLICK,look);
}
public function look(evt:MouseEvent):void{
trace("发生事件的对象"+evt.target.name);
trace("正在监听目标"+evt.currentTarget.name);
trace("当前事件流监听阶段"+evt.eventPhase);
trace("======================");
}
public function draw(obj:Sprite,x:uint,y:uint,color:uint,w:uint,h:uint):void{
obj.graphics.beginFill(color);
obj.graphics.drawRect(x,y,w,h);
obj.graphics.endFill();
}
}
}
点击最内层
3为冒泡阶段 2为目标阶段
发生事件的对象外
正在监听目标外
当前事件流监听阶段2
======================
发生事件的对象外
正在监听目标instance2
当前事件流监听阶段3
======================
发生事件的对象外
正在监听目标instance3
当前事件流监听阶段3
======================
错误及异常处理
flash.errors包
flash.events.ErrorEvent事件异常
错误捕获
package{
import flash.display.Sprite;
import flash.errors.StackOverflowError;
public class d55 extends Sprite{
public function d55(){
try{
abc();
}catch(e:StackOverflowError){
trace(e);
}catch(其他错误){
}finally{
// 最终都会执行
}
}
private function abc():void{
abc();//自身调用自身 产生堆栈错误
}
}
}
抛出错误
package{
import flash.display.Sprite;
import flash.errors.StackOverflowError;
public class d55 extends Sprite{
public function d55(){
try{
throw new Error("abc");
}catch(e:Error){
trace(e);
}
}
}
}
自定义异常
as3抛出异常 程序继续执行
异常事件
flash.events.ErrorEvent
var a:URLLoader = new URLLoader();
a.addEventListener(IOErrorEvent.IO_ERROR,error);
a.load(new URLRequest("a.jpg"));
function error(evt:IOErrorEvent):void{
trace(evt)
}