我无法理解这一点。我在Flash Professional CS5基础培训中查看了lynda.com ActionScript 3.0。我理解所有其他的东西,但这家伙把一个滑冰选手放在舞台上,他在主时间线的第一帧上有这个代码:
import flash.display.MovieClip;
import flash.events.MouseEvent;
var boarder:MovieClip = boarder_mc;
boarder.stop();
boarder.x = 0;
boarder.y = 0;
boarder.addEventListener(MouseEvent.CLICK, clickedBoarder);
function clickedBoarder(evt:MouseEvent):void
{
boarder.gotoAndPlay(2);
}
function restart():void
{
boarder_mc.gotoAndStop(1);
boarder_mc.x = 0;
}
然后在滑冰者身上,他有一个显示对象容器(电影剪辑),其中有一个滑冰者的位图图像的显示对象。在最后一帧上,他有:
stop();
parent.restart();
他解释说,这可能不起作用,他得到了一个错误:
1061: Call to a possibly undefined method restart through a reference with static type flash.display:DisplayObjectContainer.
他解释说,它知道主时间线上有一个stop()函数,也知道主时间线上有一个restart函数,但数据类型不同。他还说,父母是主要的时间线。
他说我们需要放置Object(parent).restart();
我的问题是什么数据类型,主时间线是什么(Movieclip、DisplayObject、DisplayObject Container)?
为什么它是不同的数据类型?
感谢
主时间线是MovieClip,或者如果您有DocumentClass,那么可能是一个至少扩展MovieClipe的自定义类型。
然而,当你要求你的滑冰选手MovieClip的"父"时,你实际上是在使用MovieClipe从DisplayObject继承的父属性(ActionScript Docs Here)。这个属性以DisplayObjectContainer类型返回父对象,而不管它实际是什么类型。由于它是DisplayObject的父对象,所以无论它是什么类型,它都必须扩展DisplayObjectContainer,所以它就是这样返回的。
因此,当编译ActionScript时,编译器会查看"parent",并将其视为DisplayObjectContainer类型,查看其对DisplayObjectContainer的定义和错误,因为DisplayObjectContainer没有名为"restart"的函数。
你所说的"停止"功能并不正确,因为你不是在主时间线上调用停止,而是在Skater的时间线上调用了停止。如果你想在主时间线上调用stop,你需要调用parent.stop(),这会给你同样的错误,因为DisplayObjectContainer没有一个名为stop的方法。
这两个都是编译器错误,是因为编译器遵循一组规则,并且它不能对程序运行时可能发生的实际情况做出假设。它只知道,当您调用parent.restart()时,它可能会收到一个DisplayObjectContainer,该容器上不会重新启动该方法,并且会发生运行时错误。
现在,通过将parent强制转换为类型object,您可以有效地告诉编译器,这个东西上可以有任何方法或属性,因为object是一个动态类。因此,编译器现在将假设您作为开发人员知道方法"restart"将存在于提供给该代码位的"Object"上,因此不会再出错。
非常感谢您的回复。这真是令人困惑。我认为DisplayObjectContainer是DisplayObject的一个子类,它对它进行了扩展?我知道显示对象容器是一个显示对象,它可以包含其他显示对象和显示对象容器。因此,按照我的理解,主时间线是一个movieclip,因此是DisplayObejctContainer,它可以包含其他Display对象(您在应用程序中创建的),这就是为什么parent返回Display Object Container,但它也是一个抽象类,这意味着它不能有.restart和goToAndPlay()等方法,因为它实际上无法实例化。然而,如果这是一个电影剪辑,正如你所说,那么它可以。。。。。我不明白。这是不是意味着这是一堂抽象课?