2016-03-07 181 views
0

我需要创建一个像这样的东西。Flex/AS3动态创建类

var s:String; 
var b1:Boolean; 
if (b1==true) 
    s="Class1()" 
else 
    s="Class2()"; 
var o:Object; 
o = new [s]() // create or new Class1(), or new Class2 
+1

为什么它需要是一个字符串?为什么不制作Class1和Class2都实现的接口?还是一个他们都继承的类? – DodgerThud

+0

您可以改为创建一个引用,如:ref ['myclass'] = MyClass,然后简单地执行new ref ['myclass'](); – BotMaster

+0

谢谢,但我有这条线的错误“var classType:Class = somethingIsTrue?Class1:Class2;” 1120:访问未定义的属性somethingIsTrue – Alex

回答

1

您还没有给出太多的信息,所以我不知道你是否真的需要做到这一点,但也有可能你的几个很好的理由,并且它可以使用getDefinitionByName做到:

var className:String = somethingIsTrue ? "Class1" : "Class2"; 
var classType:Class = getDefinitionByName(className) as Class; 
if (classType) 
    trace(new classType()); 

需要注意的是:

  • 类名必须是完全合格的,如果你的类在包中必须包含包的意思。例如:"path.to.my.stuff.Class1"
  • 如果代码中没有对该类的“真实”引用(类名字串不计算在内),它将不会被编译到您的SWF中,因此getDefinitionByName将找不到它。解决此问题的最简单方法是在某处放置类型声明,如var a:Class1, b:Class2。另一种方法是将这些类放在一个swc库中。
  • 使用getDefinitionByName非常慢(谢谢@Philarmon),所以要清楚:避免这种情况,除非你真的必须这样做。

编辑:下面是一个使用字符串没有的你如何能做到这一点的例子:

var classType:Class = somethingIsTrue ? Class1 : Class2; 
var instance:Object = new classType(); 

正如你所看到的,你不必使用字符串如果你事先知道班级名称。事实上,你不知道,提前知道类名是罕见的。

即使你已经开始用字符串(比如从JSON序列化的用户数据),只要你提前知道时间的类名,你可以将字符串映射到类的引用:

var classes:Object = { 
    "alfa": Class1, 
    "bravo": Class2 
} 

var className:String = "alfa"; 
var instance:Object = new classes[key]; 
+0

请记住,尽管getDefinitionByName()死了很慢,所以如果您需要以这种方式创建大量的东西,最好直接传递类名或者 - 如果它必须是字符串 - 只需进行映射类将返回一个基于字符串的类名称 – Philarmon

+0

确实,如果有一种方法可以*不依赖字符串,它肯定会更好。 OP在这一点上并没有做出这样的选择。 – Aaron

+0

谢谢,但我有这条线的错误 “var classType:Class = somethingIsTrue?Class1:Class2;” 1120:未定义财产的访问somethingIsTrue – Alex

0

不知道你的情况背后的原因,很可能你正在寻找的是一个接口。首先创建一个接口(见here为例):

public interface MyInterface { 
    //Include any methods the classes should implement here 
} 

然后每一类都应该实现的接口:

public class Class1 implements MyInterface 

最后,创建它们的时候,你可以做这样的:

var o:MyInterface; 
if (b1 == true) 
    o = new Class1(); 
else 
    o = new Class2();