Flash 将子类强制转换为父变量as3

Flash 将子类强制转换为父变量as3,flash,actionscript-3,actionscript,flash-cs4,Flash,Actionscript 3,Actionscript,Flash Cs4,我在循环中调用不同类型的类。对象可以是不同的类型,因此我使用getDefinitionByName方法。下面是我的一段代码: for(var y = 0; y < mapH; y++) { brickHolder[y] = new Array(); for(var x = 0; x < mapW; x++) { var cla

我在循环中调用不同类型的类。对象可以是不同的类型,因此我使用getDefinitionByName方法。下面是我的一段代码:

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:IBrick = IBrick(new classRef());
但是当我尝试调用方法时,我遇到了一个错误。界面为空;里面没有任何方法。我不确定这是否有区别。但是父类继承它,子类继承父类。我可以改为使用父类吗

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

简而言之,我可以做些什么来松散地强制转换这些对象,以便能够使用任何被调用的子类方法?

最好的方法是使用一个接口并定义将在接口中使用的所有常用方法。这将确保所有实现都有正确的方法和正确的签名,并在任何地方都提供类型安全性,但按名称获取类的反射除外

一个非常糟糕的方法是将brick作为Object或*类型,这将允许您调用任何想要的方法,并且如果该方法不存在,只会在运行时而不是编译时给您一个错误。这是一个糟糕的黑客行为,如果可能的话,你应该避免

您还可以使用duck类型化方法,在这种方法中,您可以将brick作为对象键入,但只有在确认方法确实存在时才调用这些方法

var brick:Object = new classRef();
if ("getBall" in brick)
    brick.getBall();
不会为您提供任何编译时类型安全性,但会避免运行时错误,前提是跳过缺少的方法是可以接受的。

[UPDATE]在深入研究之后,编译器似乎忽略了virtual关键字,因此这不起作用。AS3的另一个缺点是:

我认为多态性是你追求的概念。我认为你可以在AS3虚拟关键词存在的情况下做到这一点


是的,您应该绝对能够使用父类,例如:

var c:Car = new Mercedes();
对于接口情况,您应该只调用接口定义的函数。而且有一个空白的界面根本没有意义

如果我没有记错我的AS3怪癖,方法和成员名称检查是在运行时完成的,您应该能够调用对象上的任何函数。因此,您也可以将所有内容都强制转换为对象:

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

但请使用汽车示例中的父类型。这是正确的多态性。

我得出的结论是,最好的方法是创建一个工厂来获取所需的类,并使用父类来捕获您所寻找的类的引用。这样,您仍然能够继承子类属性和方法以及父类。我想这是最好的了。我试图使用接口捕获类的引用,但抛出了一个错误。因此,我猜在使用它的方法之前,您必须强制转换一个接口变量。我可能错了

我试过了。它不起作用。基类是Brick。子类是Brick2。我这样做了-var classRef=getDefinitionByName'com.objects.Brick2'作为类;var brick:brick=brickclassref;我犯了个错误。ReferenceError:Error1065:未定义变量Brick2。是的,我理解在接口中没有任何方法没有多大意义。但是现在,我正试图做任何事情让我的班级变得松散。所以我可以在循环中添加任何子类。不过,您在哪里提到“Brick2”?错误消息没有意义。您是否尝试传递类而不是使用getDefByName?您是否尝试过公开Brick2和/或在获取定义时显示Brick2的定义。。。呼叫i、 你能说var x=新砖2吗;在for循环中?是的,或者更好。如果我铸造砖块;进入Brick2类型的变量时,它起作用,但如果接收变量是Brickhaha类型,则不起作用,所以如果直接启动Brick2进入Brick类型的变量时,它起作用。只是如果您使用getDefinitionByName检索该类,然后设置它,那么它就不起作用了。我认为这很愚蠢,因为它在某种程度上违背了使用getDefinitionByName方法的目的。任何使用它的人,8/10可能是调用多种类型的类。但是,如果您已经知道该类型,那么当您可以直接调用它时,为什么还要使用它呢。别误会,getDefinitionByName确实有用。但您必须首先将其转换到方法中。你最好直接做。这正是我想要的。除非我在没有调用任何方法的情况下也会出错。到目前为止,我还没有将关键字virtual添加到我的函数中。但是当我试图将我的子类转换为父类变量时,我需要这样做吗。。。基类是Brick。子类是Brick2。我这样做了-var classRef=getDefinitionByName'com.objects.Brick2'作为类;var brick:brick=brickclassref;我犯了个错误。ReferenceError:错误1065:未定义变量Brick2。不幸的是,在AS3中挖掘虚拟关键字之后,现在只不过是一个占位符。编译器将忽略它:。如果你
将Brick2强制转换为Brick类型的变量并调用重写函数,然后它将调用Brick函数而不是Brick2函数。如果存在虚拟函数,那么就可以在一个Brick实例上调用Brick2重写函数。明白了。所以从现在开始,它可能只是为了将来的某件事。所以AS3不一定有真正的多态性。当然有接口,但只是为了保持类之间的契约。实际上,没有任何可行的方法来创建松散的类型类。从目前为止我所得到的。我担心的是,我将不得不创建某种类型的工厂,根据所提供的类的类型来保存一系列case语句。即使这样也不行。如果我创建了一个返回请求类的工厂,我必须指定返回值。这将限制我只返回一种数据类型。是的,没有真正的多态性:我还需要做类似的事情。我想也许你可以使用一个非类型化的类返回,然后“知道”你可以使用它。。这可能行得通,但不是最好的结果我试过了,但我出错了。但是就像你说的,我不想用这个。我宁愿保持面向对象。至于第二个建议。这是一个好主意,但并不完全是我想要的。父类完成了大部分工作。如果有的话,我重写父类方法来做一些不同的事情。
var brick:Object = new classRef(); //or cast to Object
brick.name = x + "" + y;
brick.getBall(ball);