Why Flex allows me to treat a class as an object

This code is flawed as it adds the class to the array and then tries to pull it out and manipulate it as if it were an object.

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];
}

      

When I did it by accident, it took me forever to see what I did wrong. Partly because the error message didn't tell me anything I could understand:

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]

      

So my question is why the line is marked !! BAD !! above is even allowed? I would expect a compile time error. Since it compiles, there must be some use for this that I am not aware of. What is it?

+1


source to share


4 answers


The question seems to me to be equivalent: "Why can I use a class as a value?" That's a good question.

There are two main things you can do with a class in ActionScript; you can instantiate and you can access static properties. (Okay, there are other things, but these are obvious.) Instantiating a class is probably the most important use of a class as a value; The class is its own factory , like the ones you explicitly specify in C ++ or Java.

Here is an example from a small Tetris game I wrote as an exercise. I had two classes, Brick and SceneBrick. Brick has been in the game of bricks, the ones that fall and accumulate. The SceneBrick was a brick, simply drawn as a play area frame.

However, I used one function to draw both of them without accessing either type within the function:



function drawBricks(xs:Array, ys:Array, brickType:Class){
 xs.map(function(o,i,a){
  var brick = new brickType();
  // etc.
 });    
}

      

And I could use it like this:

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"

      

In ActionScript, you can pass a class as a value and use it to instantiate that class. In a language like Java or C ++, you will either have to use it as a parameter to a generic class, or define factory classes with some generic supertype to do this.

+8


source


I am assuming that the exception occurred on the last line of your sample, and not in the error you marked with "BAD".

What you added to the array was an object that represented the class MyClass, not an instance of MyClass.



The ability to explore classes at runtime is a powerful feature and is the foundation of reflection functionality in .NET and Java. These functions are often used to support extensibility patterns or implement serialization schemes.

So manipulating one of these objects is the right thing to do ... because it is not an instance of MyClass, so you cannot assign it to your y variable.

+7


source


It seems that in Flex, collections do not specify the type of values ​​they should contain.

var a:ArrayCollection = new ArrayCollection();

      

So it seems logical to me that the compiler does not check the types of the values ​​you added. Then the assignment of variables from the elements of the collection can only be checked at runtime, since the compiler has no information.

With regard to classes being objects (and responding to messages), it is very convenient to create all kinds of debug / validation / reflection tools.

+1


source


The good thing about late binding (and dynamic languages) is that it allows you a lot more flexibility in implementation. The downside is that the language doesn't protect you from making some simple mistakes that prevent early binding and strong typing. Personally, I would consider using TDD (Test Driven Development) as a means of preventing such errors from creeping in your code.

0


source







All Articles