这段代码很无聊,因为它为一个数组添加了一个类,然后尝试将它拉出来并像操作它一样操纵它.
private function fail(event:Event):void { var myObj:MyClass; var a:ArrayCollection = new ArrayCollection(); var x:MyClass; var y:MyClass; myObj = new MyClass; a.addItem(myObj); a.addItem(MyClass); // !!BAD!! x = a[0]; y = a[1]; }
当我意外地做到这一点时,我花了很长时间才看到我做错了什么.部分是因为错误消息没有告诉我任何我能理解的内容:
TypeError: Error #1034: Type Coercion failed: cannot convert com.ibm.ITest::MyClass$ to com.ibm.ITest.MyClass. at ITest/fail()[C:\work_simple01\ITest\src\ITest.mxml:51] at ITest/___ITest_Button5_click()[C:\work_simple01\ITest\src\ITest.mxml:61]
所以我的问题是,为什么标记线!!坏!以上甚至允许?我希望这里有编译时错误.由于它编译,必须有一些用途,我不知道.它是什么?
在我看来,这个问题等同于"为什么我可以将一个类用作值?" 这是一个很好的问题.
在ActionScript中,您可以使用两个主要的功能; 你可以实例化它,你可以访问它的静态属性.(好吧,还有其他的东西,但那些是显而易见的.)实例化一个类可能是一个类作为一个值最相关的用法; Class是它自己的工厂,就像你在C++或Java中明确制作的那样.
这是我作为练习写的一个小型俄罗斯方块游戏的例子.我有两个课,Brick和SceneBrick.一块砖是游戏中的砖块,那些落下并堆积起来的砖块.SceneBrick是一块刚刚作为游戏区框架绘制的砖块.
但是,我使用一个函数来绘制它们,而不引用函数中的任何一个类型:
function drawBricks(xs:Array, ys:Array, brickType:Class){ xs.map(function(o,i,a){ var brick = new brickType(); // etc. }); }
我可以像这样使用它:
drawBricks([0,1,2,3], [4,4,4,4], Brick); // draw a long piece drawBricks(times(0, 21), countFrom(0, 21), SceneBrick); // draw a big vertical "wall"
在ActionScript中,您可以将类作为值传递,并使用它来实例化该类.在Java或C++等语言中,您必须将其用作泛型类的参数,或者使用一些常用的超类型定义工厂类才能执行此操作.
我假设异常发生在您的样本的最后一行,而不是您标记为'BAD'的错误.
您添加到数组中的是表示"MyClass"类的对象,而不是MyClass的实例.
能够在运行时检查类是一个强大的功能,是.NET和Java中反射功能的基础.这些功能通常用于支持可扩展性模式或实现序列化框架.
因此,操纵其中一个对象是有效的事情......因为它不是MyClass的实例,所以你不能将它分配给你的y变量.