Tutorial :Casting a subclass into a parent variable as3



Question:

I am calling on different types classes from within a loop. The objects can be of different types so therefore I am using the getDefinitionByName method. here is a piece of my code:

for(var y = 0; y < mapH; y++)              {                  brickHolder[y] = new Array();                  for(var x = 0; x < mapW; x++)                  {                      var classRef = getDefinitionByName('com.objects.Brick2') as Class;                      var brick:Brick2 = Brick2(new classRef());                      brick.name = x+""+y;                      brick.getBall(ball);                      brick.getEngine(this);                      brick.x = x * brick.bWidth + brick.bWidth;                      brick.y = y * brick.bHeight + 100;                      numberOfBricks += 1;                      addChild(brick);                    }              }  

Only problem is I must cast this object into a specific variable:

var brick:Brick2 = Brick2(new classRef());  

I thought about using a interface and casting it like this:

var brick:IBrick = IBrick(new classRef());  

But I got an error when I tried to call on methods. The interface is blank; doesn't have any methods in it. I am not sure if that makes a difference. But the parent class inherits it and the subclasses inherit the parent class. Can I instead use the parent class?

var brick:ParentBrick2 = ParentBrick2(new classRef());  

In a nutshell, what can I do to loosely cast these objects so I am able to use any subclass methods that get called?


Solution:1

The best way is to use an interface and define all of the common methods that you'll be using in the interface. That will ensure that all implementations have the right methods with the right signatures and provides type safety everywhere except the reflection where you get class by name.

A really bad way, which will work, is to type brick as "Object" or "*" which will allow you to call any method you want and will only give you an error at runtime instead of compile time if the method doesn't exist. This is a bad hack that you should avoid if possible.

You can also use duck-typing methodology where you type brick as "Object" but only call the methods if you confirm that they actually exist.

var brick:Object = new classRef();  if ("getBall" in brick)      brick.getBall();  

Doesn't give you any compile-time type safety, but will avoid runtime errors (assuming it's acceptable to just skip the missing methods).


Solution:2

[UPDATE] after digging around it seems the virtual keyword is ignored by the compiler so this wont work. Yet another shortcoming of AS3 :(

I think Polymorphism is the concept you are after. I think you can do it in AS3 (virtual keyword exists).

http://msdn.microsoft.com/en-us/library/ms173152%28VS.80%29.aspx <-- C# examples but explains the idea well.

When a derived class overrides a virtual member, that member is called even when an instance of that class is being accessed as an instance of the base class

So if you make your base class functions virtual then you should still be able to call the new overridden functions of the subclasses even if the instance is of the base class type.


Solution:3

Yes, you should definitely be able to use the parent class, e.g.:

var c:Car = new Mercedes();  

As for the interface case, you should only call functions defined by the interface. And having a blank interface doesn't make sense at all.

If I remember my AS3 quirks correctly, method and member name checking is done at runtime, and you should be able to call any function on an Object. So you might cast everything to Object as well:

var brick:Object = new classRef(); //or cast to Object  brick.name = x + "" + y;  brick.getBall(ball);  

But use the parent type as in the car example. That's proper polymorphism.


Solution:4

I've come to the conclusion that the best way to do it is to create a factory that gets the required class and use the parent class to catch the reference of what ever class your looking for. doing so you will still be able to inherit the subclass properties and methods and the parent class as well. This works the best I guess. I tried to catch the references of the class using an interface, but I got a an error thrown. So I am guessing you have to cast an interface varible before you can use its methods. I might be wrong


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »