2010-01-07 86 views
0

我在循環中調用不同類型的類。對象可以是不同的類型,所以我使用getDefinitionByName方法。這裏有一塊我的代碼:將子類轉換爲父變量as3

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); 

       } 
      } 

唯一的問題是我必須將此對象轉換爲特定的變量:

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

我想過使用一個接口和鑄造這樣的:

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

但是當我嘗試調用方法時出現錯誤。界面空白;沒有任何方法。我不確定這是否有所作爲。但是父類繼承了它,子類繼承了父類。我可以改爲使用父類嗎?

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

概括地說,我能做些什麼,以鬆散投這些對象,所以我能夠使用任何方法,子類是被調用?

回答

0

最好的方法是使用一個接口並定義您將在界面中使用的所有常用方法。這將確保所有實現都具有正確的方法和正確的簽名,並提供類型安全性,除了按照名稱命名的反射之外。

一個非常糟糕的方式,這將工作,鍵入磚作爲「對象」或「*」,這將允許您調用任何你想要的方法,只會給你一個錯誤在運行時而不是編譯時,如果方法不存在。如果可能的話,這是一個很糟糕的黑客。

你也可以在你輸入brick作爲「Object」的情況下使用鴨式輸入法,但只有在確認它們確實存在時才調用方法。

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

不給你任何的編譯時類型安全,但會避免運行時錯誤(假設它是可以接受的只是跳過缺少的方法)。

+0

以及我試過的對象,我得到一個錯誤。但就像你說的,我不想使用它。我寧願保持面向對象。至於第二個建議。這是一個好主意,但它並不完全是我所期待的。父類完成大部分工作。如果有的話,我重寫父類的方法來做一些不同的事情。 – numerical25 2010-01-07 04:38:55

0

[UPDATE]挖掘它後似乎虛擬關鍵字被編譯器忽略,所以這不會工作。 。然而,AS3 :(

的另一個缺點我覺得多態性是你所追求的概念,我認爲你可以做到這一點在AS3(virtual關鍵字存在)

http://msdn.microsoft.com/en-us/library/ms173152%28VS.80%29.aspx < - C#例子,但說明了想法好。

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

所以,如果你讓你的基類的虛函數,那麼你應該仍然能夠調用子類的新重載函數即使該實例是基類的。

+0

這正是我正在尋找的。即使沒有調用任何方法,我也會收到錯誤信息。截至目前,我還沒有將虛擬關鍵字添加到我的功能中。但我是否需要,當我只是試圖將我的子類轉換爲父類varible時...基類是Brick()。子類是Brick2。我這樣做 - var classRef = getDefinitionByName('com.objects.Brick2')作爲類; var brick:Brick = Brick(new classRef());我得到了一個錯誤。 ReferenceError:錯誤#1065:變量Brick2未定義。 – numerical25 2010-01-07 04:32:25

+0

不幸的是,在AS3中挖掘虛擬關鍵字後,現在僅僅是一個佔位符。編譯器會忽略它:(。 如果您將Brick2投射到Brick類型的變量並調用覆蓋函數,那麼它將調用Brick函數而不是Brick2函數。如果存在虛函數,則可能會調用Brick2在Brick實例上被重寫的函數 – Allan 2010-01-07 04:44:23

+0

所以現在,它可能只是爲了將來的某些事情,所以AS3並不一定有真正的多態性,當然這些接口,只是爲了在類之間保持契約。沒有合理的方式來製作寬鬆的班級,從我到目前爲止,我所要做的就是創建一些類型的工廠,根據所提供的班級類型,制定一系列的案例陳述 – numerical25 2010-01-07 05:09:20

0

是的,你一定要能夠使用父類,例如:

var c:Car = new Mercedes(); 

至於接口的情況下,你應該只調用接口定義功能。有一個空白的界面根本沒有意義。

如果我正確記住我的AS3怪癖,方法和成員名稱檢查在運行時完成,並且您應該可以調用Object上的任何函數。因此,您可能會將所有對象都投射到對象:

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

但是,在汽車示例中使用父類型。這是正確的多態性。

+0

我試過了。它不起作用。基類是Brick()。子類是Brick2。我這樣做 - var classRef = getDefinitionByName('com.objects.Brick2')作爲類; var brick:Brick = Brick(new classRef());我得到了一個錯誤。 ReferenceError:錯誤#1065:變量Brick2未定義。 – numerical25 2010-01-07 04:25:41

+0

是的,我明白它沒有任何意義,沒有任何方法在接口。但就目前而言,我正在努力做任何事情來讓我的班級變得鬆散。所以我可以在循環中添加任何子類。 – numerical25 2010-01-07 04:35:40

+0

雖然你在哪裏提到'Brick2'?錯誤消息沒有意義。你有沒有嘗試傳遞'Class'而不是使用getDefByName()?您是否嘗試將Brick2公開並/或在getDef ...()調用時使Brick2的定義可見? (也就是說,你可以在for循環中說'var x = new Brick2();' – aib 2010-01-07 05:16:57

0

我得出的結論是,最好的辦法是創建一個工廠,獲取所需的類並使用父類來捕獲您尋找的任何類的引用。這樣做,您仍然可以繼承子類的屬性和方法以及父類。這是最好的我猜。我試圖用接口捕捉類的引用,但是我得到了一個錯誤。所以我猜你在使用它的方法之前必須先創建一個接口變量。我可能是錯的