|
AS3 中的反射 AS3 中的反射 2
动态获取类名称, 超类 (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
代码拷贝
package { import flash.display.Sprite; import flash.utils.getDefinitionByName; import flash.utils.getQualifiedClassName; import flash.utils.getQualifiedSuperclassName; public class ReflectionSample extends Sprite { public function ReflectionSample () { getClassNameSample(); } /** * 使用 flash.utils.getQualifiedClassName 和 getQualifiedSuperclassName 获取类名称, 并动态创建该类 * */ private function getClassNameSample ():void { var sprite1:Sprite = new Sprite(); var classNameOfSprite:String = getQualifiedClassName(Sprite); trace("Sprite 的类名 : " + classNameOfSprite); var superclassNameOfSprite:String = getQualifiedSuperclassName(Sprite); trace("Sprite 的超类 (基类) 类名 : " + superclassNameOfSprite); var SpriteClass:Class = getDefinitionByName(classNameOfSprite) as Class; var sprite2:Sprite = new SpriteClass() as Sprite; trace("sprite2 通过 getDefinitionByName 创建 Sprite 实例"); sprite2.graphics.beginFill(0xFF00FF); sprite2.graphics.drawRect(0, 0, 100, 100); sprite2.graphics.endFill(); addChild(sprite2); } } }
获取类信息
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 的标签和属性 (按运行代码察看) ------------------------------------------------------------代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <style type="text/css"> * table, td, th th </style> </head> <body> <table width="100%"> <tr><th>标签</th><th>属性</th><th>说明</th></tr> <tr><td><code><type></code></td><td> </td><td>XML 对象的根标签</td></tr> <tr><td> </td><td>name</td><td>ActionScript 对象 (ActionScript object) 类型</td></tr> <tr><td> </td><td>base</td><td>当前对象的直属超类, 如果当前 ActionScript 对象是类对象, 那那么该值为 <code>Class</code>.</td></tr> <tr><td> </td><td>isDynamic</td><td>如果当前 ActionScript 对象被定义为 dynamic, 那么该属性为 <code>true</code>, 否则为 <code>false</code>. 如果当前 ActionScript 对象是类对象, 那么该属性也为 <code>true</code>, 因为 Class 类是 dynamic 的</td></tr> <tr><td> </td><td>isFinal</td><td>如果当前 ActionScript 对象被定义为 final, 那么该属性为 <code>true</code>, 否则为 <code>false</code></td></tr> <tr><td> </td><td>isStatic</td><td>如果当前 ActionScript 是类对象或者构造函数, 那么该属性为 <code>true</code>, 否则为 <code>false</code>. 该属性被命名为 <code>isStatic</code> 是因为如果值为 <code>true</code> 的话, 任何标签都不会被嵌套到 <code>factory</code> 标签中</td></tr> <tr><td><code><extendsClass></code></td><td> </td><td>使用 <code>extendsClass</code> 标签分别存放当前 ActionScript 对象的超类</td></tr> <tr><td> </td><td>type</td><td>当前 ActionScript 对象所继承的超类的名字</td></tr> <tr><td><code><implementsInterface></code></td><td> </td><td>使用 <code>implementsInterface</code> 标签分别存放当前 ActionScript 对象, 以及他的超类所实现的接口</td></tr> <tr><td> </td><td>type</td><td>当前 ActionScript 所实现的接口的名字</td></tr> <tr><td><code><accessor></code></td><td> </td><td>访问器是由 getter 和 setter 所定义的属性</td></tr> <tr><td> </td><td>name</td><td>该访问器的名字</td></tr> <tr><td> </td><td>access</td><td>该访问器的访问权限. 可能的值有 <code>readonly</code>, <code>writeonly</code>, 和 <code>readwrite</code>.</td></tr> <tr><td> </td><td>type</td><td>该属性的数据类型</td></tr> <tr><td> </td><td>declaredBy</td><td>指示由哪个类定义了该访问器</td></tr> <tr><td><code><constant></code></td><td> </td><td>常量是由 <code>const</code> 所定义的属性</td></tr> <tr><td> </td><td>name</td><td>该常量的名称</td></tr> <tr><td> </td><td>type</td><td>该常量的数据类型</td></tr> <tr><td><code><method></code></td><td> </td><td>方法是由类定义的一部分公开的函数</td></tr> <tr><td> </td><td>name</td><td>方法名</td></tr> <tr><td> </td><td>declaredBy</td><td>指示该方法由哪个类定义</td></tr> <tr><td> </td><td>returnType</td><td>方法的返回类型</td></tr> <tr><td><code><parameter></code></td><td> </td><td>使用 <code>parameter</code> 分别存放该方法的参数, 该标签被嵌套在 <code><method></code> 中</td></tr> <tr><td> </td><td>index</td><td>一个数字指示当前参数被传递时所在函数中的位置, 如果是首个参数, 那么该值为 1</td></tr> <tr><td> </td><td>type</td><td>该参数的类型</td></tr> <tr><td> </td><td>optional</td><td>如果该参数为可选的话为 <code>true</code>, 否则为 <code>false</code></td></tr> <tr><td><code><variable></code></td><td> </td><td>变量 (variable) 是由 var 语句所定义的变量</td></tr> <tr><td> </td><td>name</td><td>变量名</td></tr> <tr><td> </td><td>type</td><td>变量类型</td></tr> <tr><td><code><factory></code></td><td> </td><td>如果当前 ActionScript 对象是类对象或者构造函数, 所有的实例属性将会被嵌套进该标签. 如果 <code><type></code> 标签的 <code>isStatic</code> 属性为 <code>true</code>, 所有属性 (properties) 和方法 (method) 将不会被嵌套进改标签中. 该标签只出现在当前 ActionScript 对象是类对象或者构造函数的情况下</td></tr> </table> </body> </html>
另外, 由 describeType() 返回的类描述信息中只会含有所有可被访问的元素, 即所有非定义为 private 的元素.
解释了这么多, 我们来看看返回的 XML 格式 flash 的内置类 flash.display.Sprite :
trace(describeType(Sprite); 返回:
代码拷贝
<type name="flash.display::Sprite" base="Class" isDynamic="true" isFinal="true" isStatic="true"> <extendsClass type="Class"/> <extendsClass type="Object"/> <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/> <factory type="flash.display::Sprite"> <extendsClass type="flash.display::DisplayObjectContainer"/> <extendsClass type="flash.display::InteractiveObject"/> <extendsClass type="flash.display::DisplayObject"/> <extendsClass type="flash.events::EventDispatcher"/> <extendsClass type="Object"/> <implementsInterface type="flash.display::IBitmapDrawable"/> <implementsInterface type="flash.events::IEventDispatcher"/> <accessor name="hitArea" access="readwrite" type="flash.display::Sprite" declaredBy="flash.display::Sprite"/> <method name="startDrag" declaredBy="flash.display::Sprite" returnType="void"> <parameter index="1" type="Boolean" optional="true"/> <parameter index="2" type="flash.geom::Rectangle" optional="true"/> </method> <accessor name="buttonMode" access="readwrite" type="Boolean" declaredBy="flash.display::Sprite"/> <accessor name="graphics" access="readonly" type="flash.display::Graphics" declaredBy="flash.display::Sprite"/> <accessor name="soundTransform" access="readwrite" type="flash.media::SoundTransform" declaredBy="flash.display::Sprite"/> <method name="stopDrag" declaredBy="flash.display::Sprite" returnType="void"/> <accessor name="dropTarget" access="readonly" type="flash.display::DisplayObject" declaredBy="flash.display::Sprite"/> <accessor name="useHandCursor" access="readwrite" type="Boolean" declaredBy="flash.display::Sprite"/> <method name="getChildAt" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="int" optional="false"/> </method> <method name="addChild" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <method name="swapChildren" declaredBy="flash.display::DisplayObjectContainer" returnType="void"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> <parameter index="2" type="flash.display::DisplayObject" optional="false"/> </method> <method name="getChildByName" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="String" optional="false"/> </method> <method name="getObjectsUnderPoint" declaredBy="flash.display::DisplayObjectContainer" returnType="Array"> <parameter index="1" type="flash.geom::Point" optional="false"/> </method> <accessor name="textSnapshot" access="readonly" type="flash.text::TextSnapshot" declaredBy="flash.display::DisplayObjectContainer"/> <method name="removeChildAt" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="int" optional="false"/> </method> <method name="getChildIndex" declaredBy="flash.display::DisplayObjectContainer" returnType="int"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <method name="areInaccessibleObjectsUnderPoint" declaredBy="flash.display::DisplayObjectContainer" returnType="Boolean"> <parameter index="1" type="flash.geom::Point" optional="false"/> </method> <accessor name="mouseChildren" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObjectContainer"/> <method name="removeChild" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <method name="setChildIndex" declaredBy="flash.display::DisplayObjectContainer" returnType="void"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> <parameter index="2" type="int" optional="false"/> </method> <method name="contains" declaredBy="flash.display::DisplayObjectContainer" returnType="Boolean"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <method name="addChildAt" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> <parameter index="2" type="int" optional="false"/> </method> <accessor name="numChildren" access="readonly" type="int" declaredBy="flash.display::DisplayObjectContainer"/> <method name="swapChildrenAt" declaredBy="flash.display::DisplayObjectContainer" returnType="void"> <parameter index="1" type="int" optional="false"/> <parameter index="2" type="int" optional="false"/> </method> <accessor name="tabChildren" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObjectContainer"/> <accessor name="tabEnabled" access="readwrite" type="Boolean" declaredBy="flash.display::InteractiveObject"/> <accessor name="doubleClickEnabled" access="readwrite" type="Boolean" declaredBy="flash.display::InteractiveObject"/> <accessor name="contextMenu" access="readwrite" type="flash.ui::ContextMenu" declaredBy="flash.display::InteractiveObject"/> <accessor name="accessibilityImplementation" access="readwrite" type="flash.accessibility::AccessibilityImplementation" declaredBy="flash.display::InteractiveObject"> <metadata name="Inspectable"> <arg key="environment" value="none"/> </metadata> </accessor> <accessor name="mouseEnabled" access="readwrite" type="Boolean" declaredBy="flash.display::InteractiveObject"/> <accessor name="focusRect" access="readwrite" type="Object" declaredBy="flash.display::InteractiveObject"/> <accessor name="tabIndex" access="readwrite" type="int" declaredBy="flash.display::InteractiveObject"/> <accessor name="mask" access="readwrite" type="flash.display::DisplayObject" declaredBy="flash.display::DisplayObject"/> <accessor name="scaleX" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="scaleY" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <method name="getRect" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Rectangle"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <accessor name="mouseY" access="readonly" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="alpha" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="x" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="name" access="readwrite" type="String" declaredBy="flash.display::DisplayObject"/> <accessor name="y" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="root" access="readonly" type="flash.display::DisplayObject" declaredBy="flash.display::DisplayObject"/> <accessor name="width" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="stage" access="readonly" type="flash.display::Stage" declaredBy="flash.display::DisplayObject"/> <accessor name="loaderInfo" access="readonly" type="flash.display::LoaderInfo" declaredBy="flash.display::DisplayObject"/> <accessor name="transform" access="readwrite" type="flash.geom::Transform" declaredBy="flash.display::DisplayObject"/> <accessor name="height" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <method name="localToGlobal" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Point"> <parameter index="1" type="flash.geom::Point" optional="false"/> </method> <accessor name="filters" access="readwrite" type="Array" declaredBy="flash.display::DisplayObject"/> <accessor name="blendMode" access="readwrite" type="String" declaredBy="flash.display::DisplayObject"/> <accessor name="rotation" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <method name="hitTestObject" declaredBy="flash.display::DisplayObject" returnType="Boolean"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <accessor name="scale9Grid" access="readwrite" type="flash.geom::Rectangle" declaredBy="flash.display::DisplayObject"/> <accessor name="accessibilityProperties" access="readwrite" type="flash.accessibility::AccessibilityProperties" declaredBy="flash.display::DisplayObject"/> <accessor name="scrollRect" access="readwrite" type="flash.geom::Rectangle" declaredBy="flash.display::DisplayObject"/> <accessor name="cacheAsBitmap" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObject"/> <method name="globalToLocal" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Point"> <parameter index="1" type="flash.geom::Point" optional="false"/> </method> <method name="getBounds" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Rectangle"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <accessor name="opaqueBackground" access="readwrite" type="Object" declaredBy="flash.display::DisplayObject"/> <accessor name="parent" access="readonly" type="flash.display::DisplayObjectContainer" declaredBy="flash.display::DisplayObject"/> <method name="hitTestPoint" declaredBy="flash.display::DisplayObject" returnType="Boolean"> <parameter index="1" type="Number" optional="false"/> <parameter index="2" type="Number" optional="false"/> <parameter index="3" type="Boolean" optional="true"/> </method> <accessor name="visible" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObject"/> <accessor name="mouseX" access="readonly" type="Number" declaredBy="flash.display::DisplayObject"/> <method name="willTrigger" declaredBy="flash.events::EventDispatcher" returnType="Boolean"> <parameter index="1" type="String" optional="false"/> </method> <method name="removeEventListener" declaredBy="flash.events::EventDispatcher" returnType="void"> <parameter index="1" type="String" optional="false"/> <parameter index="2" type="Function" optional="false"/> <parameter index="3" type="Boolean" optional="true"/> </method> <method name="toString" declaredBy="flash.events::EventDispatcher" returnType="String"/> <method name="addEventListener" declaredBy="flash.events::EventDispatcher" returnType="void"> <parameter index="1" type="String" optional="false"/> <parameter index="2" type="Function" optional="false"/> <parameter index="3" type="Boolean" optional="true"/> <parameter index="4" type="int" optional="true"/> <parameter index="5" type="Boolean" optional="true"/> </method> <method name="dispatchEvent" declaredBy="flash.events::EventDispatcher" returnType="Boolean"> <parameter index="1" type="flash.events::Event" optional="false"/> </method> <method name="hasEventListener" declaredBy="flash.events::EventDispatcher" returnType="Boolean"> <parameter index="1" type="String" optional="false"/> </method> </factory> </type>
真是又臭又长啊. :o, 根据帮助中的描述, 所有的实例属性都被嵌套在了 <factory> 标签里.
|