首页 | CG软件 | CG信息 | CG教程 | 三维作品 | 设计理论 | CG加油站 | 设计鉴赏 | 社区图库 | Flash | 专题 | 顶客 | 论坛 | 博客 | 导航 | 下载 | 高级搜索
RSS
热门: 3D Total  RPC  Evermotion  效果图  创意  装修  优秀作品  Vray  艺术  欣赏

Flash AS3 中的反射 — Reflection

来源:不详 作者:佚名 时间:2007-07-06 点击:
FLASH   反射   Reflection  

谢草莓和 yhc13 提供人肉翻译机支持

什么是反射
反射 (Reflection) 是指在程序在运行时 (run-time) 获取类信息的方式. 诸如实现动态创建类实例, 方法等. 在很语言中都有相关的的实现, 如 Java 和 c# 等

反射有什么用
在 as3 与 as2 不同, 类实例中任何元素, 如变量 (variable), 访问器 (accessor, 即 getter / setter), 方法 (method) 都是不可被 for..in 遍历的 (不是默认哦, 目前我还没找到办法可以让他被遍历),
并且不管你是否继承自 Object (默认继承就是 Object, 不写也一样), 是否把类声明为 dynamic.
或许有人会问自然是 Object 的子类, 不是可以用 setPropertyIsEnumerable 来设置是否隐藏变量么.
很遗憾的是经过的我的尝试, 在类里使用 setPropertyIsEnumerable(\"属性名\") 编译器报告方法可能未定义.
随后尝试 super.setPropertyIsEnumerable(\"属性名\"), 编译通过但抛运行时错误, 同样是方法未定义 -_-
而其他方法诸如 propertyIsEnumerable(\"属性名\") 却可以正常使用

新建一个 ActionScript 项目, 分别创建下面 2 个类:

Dummy.as

代码拷贝框

[Ctrl+A 全部选择 然后拷贝]

ReflectionSample.as

代码拷贝框

[Ctrl+A 全部选择 然后拷贝]

最后测试 ReflectionSample, 记得用 debug 模式. 控制台中只会出现:

QUOTE:
------------------------------------------------------------
测试 for..in 循环, 遍历 Dummy 的实例
------------------------------------------------------------

显然 dummy 中的元素都没有被遍历出.

在 as1, 2 中很简单就可以实现的问题在 as3 得换个办法了, 谁让他们是传统的脚本语言呢.而在 as3 中, 就得通过反射来解决这个问题了. 方法会在文后介绍

动态创建实例

* 这部分内容帮助中已经有例子, 我摘要一些翻译一下, 不过我的 e 文很烂. 希望大家能看得懂.

as3 使用 flash.util.getDefinitionByName 动态获取类 (Class) 引用
帮助中该方法的描述 :

QUOTE:
------------------------------------------------------------
public function getDefinitionByName(name:String):Object
返回参数 name 中指定的类引用

参数  name:String - 类名称
返回  Object - 返回参数 name 中指定的类引用
错误  ReferenceError - 找不到参数 name 对应的公共定义
------------------------------------------------------------

使用方法如下:

获取类 flash.text.TextField 的引用. as 语句是无异常的类型转换. 如果转换失败那么目标变量将被设置成 null

var ClassReference:Class = getDefinitionByName(\"flash.text.TextField\") as Class;

实例化所引用的类, 并设置一些属性

var instance:TextField = new ClassReference() as TextField;
instance.autoSize = \"left\";
instance.text = \"我通过 getDefinitionByName 动态创建\";

最后添加到场景中并显示

addChild(instance);

修改后的 ReflectionSample.as:

代码拷贝框

[Ctrl+A 全部选择 然后拷贝]

动态获取类名称, 超类 (Superclass) 名称
有点像之前版本中的 typeof, 这个方法返回的是字符串

QUOTE:
------------------------------------------------------------
public function getQualifiedClassName(value:*):String
返回类的完全限定名 (fully qualified class name, qualified 我不知道怎么翻了..)

参数  value:* - 想要得到完全限定名的对象. 他可以是任何 ActionScript 类型, 对象实例, 简单类型如 uint 以及类类型. 
返回  String - 包含类的完全限定名的字符串
------------------------------------------------------------

QUOTE:
------------------------------------------------------------
public function getQualifiedSuperclassName(value:*):String
返回目标对象基类的完全限定名,
本函数提供比 describeType 更简便的方法来获取基类的名称
提示: 本函数限制只寻找实例的继承层次,而 describeType() 函数使用的是类对象继承.
调用 describeType() 函数时返回的是基于超类以的类继承结构. 而 getQualifiedSuperclassName() 将忽略类的继承结构直接返回最接近的继承对象
例如, 理论上 String 类继承自 Class, 但调用 getQualifiedSuperclassName(String) 时返回的是 Object. 换句话说, 不管你传递的是类还是类的实例, 他们的返回值都是一样的

参数  value:* - 任何值. 
返回  String - 基类的完全限定名, 如果没有的话返回 null
------------------------------------------------------------

例子:

实例化新的 Sprite, 然后获取他的类名并输出

var sprite1:Sprite = new Sprite();
var classNameOfSprite:String = getQualifiedClassName(Sprite);
trace(\"Sprite 的类名 : \" + classNameOfSprite); // Sprite 的类名 : flash.display::Sprite

超类

var superclassNameOfSprite:String = getQualifiedSuperclassName(Sprite);
trace(\"Sprite 的超类 (基类) 类名 : \" + superclassNameOfSprite); // Sprite 的超类 (基类) 类名 : flash.display::DisplayObjectContainer

根据刚刚获取的类名使用 创建实例

var SpriteClass:Class = getDefinitionByName(classNameOfSprite) as Class;
var sprite2:Sprite = new SpriteClass() as Sprite;
trace(\"sprite2 通过 getDefinitionByName 创建 Sprite 实例\");

画一个 100 x 100 的矩形并显示

sprite2.graphics.beginFill(0xFF00FF);
sprite2.graphics.drawRect(0, 0, 100, 100);
sprite2.graphics.endFill();
addChild(sprite2);

修改后的 ReflectionSample.as

代码拷贝框

[Ctrl+A 全部选择 然后拷贝]

获取类信息

QUOTE:
------------------------------------------------------------

public function describeType(value:*):XML
生成一个 XML 对象来描述参数中指定的 ActionScript 对象, 这个方法使 ActionScript 实现了反射编程的概念.

如果参数 value 是某类的实例, 那么返回的 XML 对象包含了此类中所有的实例属性, 但是不会包含任何的静态属性.
这种情况下你可以通过检查标签 <type> 中的 isStatic 属性来判断他, 当参数为某类的实例时, 这个值为 false.

要获取类的静态属性, 可以通过传递类本身到参数 value, 这样返回的 XML 对象不仅包括了类的静态属性, 也包括所有的实例属性.
实例属性被包含在 <factory> 标签中使它们和静态属性区别开来. 在这种情况下, <type> 标签的 isStatic 属性为 true.

提示: 如果你只需要获取对象的继承结构而不需要 describeType() 提供的其他信息, 可以使用 getQualifiedClassName() 和 getQualifiedSuperclassName() 来替代

下表描述了 describeType() 生成的 XML 的标签和属性 (按运行代码察看)
------------------------------------------------------------

运行代码框

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]

另外, 由 describeType() 返回的类描述信息中只会含有所有可被访问的元素, 即所有非定义为 private 的元素.

解释了这么多, 我们来看看返回的 XML 格式
flash 的内置类 flash.display.Sprite :

trace(describeType(Sprite);

返回:

代码拷贝框

[Ctrl+A 全部选择 然后拷贝]

真是又臭又长啊. :o, 根据帮助中的描述, 所有的实例属性都被嵌套在了 <factory> 标签里.


本文地址:http://www.cg3000.com/html/cgTutorials/Website/Flash/20070706/Flash_AS3_zhongdefanshe___Reflection_11892.shtml
上一篇:FLASH制作天气预报
下一篇:Flash电子书鼠标拖拽翻页效果原理分析
关键字:迅雷 快车 Baidu Flash 反射 Reflection
最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册
图腾CG联盟免责声明:本网站转载纯粹出于为网民传递更多信息之目的,无任何商业目的。如本网站转载稿件涉及版权等问题,请作者速来函admincg3000@163.com联系,在此,我们首先向您表示诚挚的歉意,并将尽快予以改正。本网站上发表的内容只代表作者本人之观点,本网站只出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。
赞助广告