为什么在这种情况下从Event继承不起作用?

Pan*_*sis 0 apache-flex flash inheritance actionscript actionscript-3

给出以下代码:

类CEvent:

public class CEvent extends Event
{
    public static const TYPE:String = "cEvent";

    private var m_strCode:String;
    public function get code():String
    {
        return m_strCode;
    }

    public function CEvent(pCode:String, bubbles:Boolean=false,
            cancelable:Boolean=false)
    {
        super(TYPE, bubbles, cancelable);
        m_strCode = pCode;
    }
}
Run Code Online (Sandbox Code Playgroud)

A类:

dispatchEvent(new CEvent(MY_CONST))
Run Code Online (Sandbox Code Playgroud)

B级:

m_a = new A();
m_a.addEventListener(CEvent.TYPE, onCEvent);
.
.
.

private function onCEvent(pEvent:CEvent):void
{
    switch (pEvent.code)
    {           
        case A.MY_CONST:
        dispatchEvent(pEvent);
    }
}
Run Code Online (Sandbox Code Playgroud)

C级:

m_b = new B();
m_b.addEventListener(CEvent.TYPE, onCEvent);
.
.
.
private function onCEvent(pEvent:CEvent):void
{ // breaks right here
}
Run Code Online (Sandbox Code Playgroud)

在最初从A类调度之后,当它在C类中断时我得到这个错误:

Error #1034: Type Coercion failed: cannot convert flash.events::Event@9861089 to
<path>.CEvent.
Run Code Online (Sandbox Code Playgroud)

这似乎没有多大意义,似乎完全违背了继承的工作方式.即使Adobe的dispatchEvent()实现中有代码专门通过并削减了通过继承添加的任何内容,只调度了一个"普通"事件实例,这应该会导致它在B类中断,而不是C.

有人可以解释一下吗?谢谢.

编辑:顺便说一下,更改B类代码可以使一切正常工作:

dispatchEvent(new CEvent(pEvent.code));
Run Code Online (Sandbox Code Playgroud)

我仍然需要了解问题所在.谢谢.

Sun*_* D. 6

发生此错误是因为您尚未clone()在自定义事件中实现该方法.

当您重新调度事件时(在C类中),Flash会克隆事件,而不是仅重新调度原始事件.

因此,重新分派的事件是一个普通的旧Event对象,因为这是默认clone()方法返回的内容.

通常,您应该始终clone()为自定义事件实现方法.这很简单.在这种情况下,它应该看起来像这样:

override public function clone():Event
{
    return new CEvent(m_strCode, bubbles, cancelable);
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,这是针对事件的.我不知道原因,但Flash Player会在重新分派时克隆事件.必须有一些很好的理由,但我从未发现原因.用于`clone()`方法的[docs](http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/Event.html#clone())只说你必须在自定义事件中实现`clone()`... (2认同)