我在循环中调用不同类型的类。对象可以是不同的类型,因此我使用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:Brick2 = Brick2(new classRef());
我考虑过使用界面并像这样投射:
var brick:IBrick = IBrick(new classRef());
但是当我尝试调用方法时出错了。界面空白;没有任何方法。我不确定这是否有所作为。但是父类继承它,子类继承父类。我可以改为使用父类吗?
var brick:ParentBrick2 = ParentBrick2(new classRef());
简而言之,我可以做些什么来松散地转换这些对象,以便我可以使用任何被调用的子类方法?
答案 0 :(得分:0)
最好的方法是使用接口并定义您将在界面中使用的所有常用方法。这将确保所有实现都具有正确的方法和正确的签名,并提供类型安全,除了您按名称获取类的反射。
一种非常糟糕的方法,就是将brick键入为“Object”或“*”,它允许您调用所需的任何方法,并且只会在运行时而不是编译时给出错误不存在。如果可能的话,这是一个糟糕的黑客攻击。
您也可以使用duck-typing方法,键入brick作为“Object”,但只有在确认它们确实存在时才调用方法。
var brick:Object = new classRef();
if ("getBall" in brick)
brick.getBall();
不会给你任何编译时类型的安全性,但会避免运行时错误(假设只是跳过丢失的方法是可以接受的)。
答案 1 :(得分:0)
[UPDATE]似乎编译器忽略了虚拟关键字,所以这不会起作用。 AS3的另一个缺点:(
我认为多态性是你追求的概念。我认为你可以在AS3中实现它(虚拟关键字存在)。
http://msdn.microsoft.com/en-us/library/ms173152%28VS.80%29.aspx&lt; - C#示例,但很好地解释了这个想法。
当派生类重写a时 虚拟成员,该成员被调用 即使该类的实例是 被作为一个实例访问 基类
因此,如果将基类函数设置为虚拟,那么即使实例属于基类类型,您仍应该能够调用子类的新重写函数。
答案 2 :(得分:0)
是的,您绝对应该能够使用父类,例如:
var c:Car = new Mercedes();
对于接口情况,您应该只调用接口定义的函数。并且具有空白界面根本没有意义。
如果我正确记住了我的AS3怪癖,那么方法和成员名称检查是在运行时完成的,你应该可以调用Object
上的任何函数。所以你也可以将所有内容都转换为Object:
var brick:Object = new classRef(); //or cast to Object
brick.name = x + "" + y;
brick.getBall(ball);
但是在汽车示例中使用父类型。这是正确的多态性。
答案 3 :(得分:0)
我得出的结论是,最好的方法是创建一个工厂,获取所需的类并使用父类来捕获您所寻找的类的引用。这样做,您仍然可以继承子类属性和方法以及父类。我认为这是最好的。我试图使用接口捕获类的引用,但我抛出了一个错误。所以我猜你必须先使用接口变量才能使用它的方法。我可能错了