How to choose which child class to instantiate dynamically
Question: My current project is in as3, but this is something I am curious about for
other languages as well.

I'm attempting to use a factory object to create the appropriate object
dynamically. My `LevelFactory` has a static method that returns a new instance
of the level number provided to the method. In the code calling that method, I
am able to dynamically create the buttons to call the levels like so:

    
    
    for (var i:int = 1; i < 4; i++) {
                var tempbutton:Sprite = createButton("Level " + i, 25, 25 +(60 * i), start(i));
                _buttons.push(button);
    }
    

This code just creates a simple button with the given arguments `(ButtonText,
x, y, function)`. It's working fine. The buttons are created, and clicking on
one of them calls this method with the appropriate argument

    
    
    private function start(level:int):Function {
            return function(e:MouseEvent):void {
                disableButtons();
                newLevel = LevelFactory.createLevel(level);
                addChild(newLevel);
            }
    }
    

This is all working fine; I'm just providing it for background context. The
question I have is this: Is it possible to dynamically choose the type of
object that my static function returns? Currently, I have am doing it as
follows

    
    
    public static function createLevel(level:int):Level {
            var result:Level;
            switch(level) {
                case 1: result =  new Level1(); break;
                case 2: result = new Level2(); break;
                //etc
            }
            return result;
    }
    

I should note that all of these Level1, Level2, etc. classes extend my base
level class. (Yay polymorphism!) What I would like to do is be able to do
something along the lines of

    
    
    public static function createLevel(level:int):Level {
            var result:Level;
            var levelType:String = "Level" + level;
            return new levelType();
    }
    

Obviously it's not going to work with a string like that, but is there any way
to accomplish this in as3? What about other languages, such as Java or Python?
Can you dynamically choose what type of child class to instantiate?

Update:

    
    
    import Levels.*;
    import flash.events.*;
    import flash.utils.*;
    
    public class LevelFactory
    {
    
        public static function createLevel(level:int):Level {
            var ref:Class = getDefinitionByName('Levels.' + 'Level' + level) as Class;
            var result:Level = new ref();
            return result;  
        }
    }
    

Update/Edit: getDefinitionByName seems to be what I'm looking for, but it has
a problem. It seems that the compiler will strip unused imports, which means
that unless I declare each subclass in the code ahead of time, this method
will get a reference error. How can I get around the need to declare each
class separately (which defeats the purpose of dynamic instantiation)?


Answer: Yes, you sure can, and it's very similar to the string thing that you've
provided. The only thing that you are missing is the `getDefinitionByName`
method:
[http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/package.html#getDefinitionByName()](http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/package.html#getDefinitionByName%28%29)

You can generate whatever class name you want, and what this method does is
that it searches for that class in it's namespace, and if it finds it - it
returns it as a class:

    
    
    var ClassReference:Class = getDefinitionByName("flash.display.Sprite") as Class;
    var instance:Object = new ClassReference();
    

This piece of code will instantiate a Sprite. This way you can instantiate
your classes without all those switches and cases, especially when you have to
make a hundred levels :)

Hope that helps! Cheers!

Edit:

In your case, the code should be:

    
    
    var ref:Class = getDefinitionByName('com.path.Level' + index) as Class;
    var level:Level = new ref(); // it will actually be Level1 Class
    

