2016-03-07 179 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();