Sunday, January 3, 2010

AS3 Dynamic Construction

This is a little ActionScript 3.0 programming gem I discovered ON MY OWN without Google's help...

Check out the following code:

class Animal
{
function Animal()
{
trace ("Animal has been created");
}
}

class Dog extends Animal
{
function Dog()
{
trace ("Dog has been created. Woof!");
}
}

var notADogType:Animal = new Dog(); // outputs "Dog has been created. Woof!"
var doggie:Dog = new (Object(notADogType).constructor)() // outputs "Dog has been created. Woof!"

That's all fine and dandy, but give this a whirl:

var puppy:Animal = new Dog(); // outputs "Dog has been created. Woof"
var noType:* = puppy;

var newDog:Dog = new (Object(noType).constructor)() // outputs "Dog has been created. Woof!"

This is really useful to put in a superclass of something to return a new one of that type. Take this for example:

class Thing
{
function newOne():Thing
{
return new (Object(this).constructor)();
}

function overrideMe()
{
trace ("I'm just a thing");
}
}

class Car
{
override function overrideMe()
{
trace ("I'm a car. Vroooom!");
}
}

var volvo:Thing = new Car();
volvo.overrideMe(); // outputs "I'm a car. Vroooom!"

var justAThing:Thing = volvo.newOne();
justAThing.overrideMe(); // outputs "I'm a car. Vroooom!"

This proved to be very helpful in my latest game.

Note: there are inaccuracies in the code, such as: you can't put the code in a frame and expect it to work. Also, when a subclass is constructed, its superclass's constructor is called as well. But the general concept still works.

Basically, regardless of the type of someInstance, Object(someInstance).constructor points to the class used to construct someInstance. You can use that exactly like it's a normal class, but don't forget to put parentheses around Object(someInstance).constructor. Wanna typecast? (Object(someInstance).constructor)(otherObject). Create a new one new (Object(someInstance).constructor)().

I can't believe this isn't documented very well...

No comments:

Post a Comment