Subclassing Event in AS3
Thursday May 28th, 2009I encountered an error yesterday while I was working on a seemingly simple piece of code. Considering that I should have been able to spot the error right away but didn’t, I figured I would write it down for future reference.
I was using a subclass of Event and I was getting type coercion error every time I forwarded an event to a different listener. Considering the code was nothing new, I was quickly stumped, but it all came down to a very simple mistake.
TypeError: Error #1034: Type Coercion failed: cannot convert flash.events::Event@22fcd31 to com.fm.mmc.MMCEvent.
Whenever you subclass Event you must override the clone() method. Although you will most likely never call it explicitly, the Flash Player relies on clone() whenever an event is forwarded.
From the docs:
Returns a new Event object that is a copy of the original instance of the Event object. You do not normally call clone(); the EventDispatcher class calls it automatically when you redispatch an event—that is, when you call dispatchEvent(event) from a handler that is handling event.
The new Event object includes all the properties of the original.
When creating your own custom Event class, you must override the inherited Event.clone() method in order for it to duplicate the properties of your custom class. If you do not set all the properties that you add in your event subclass, those properties will not have the correct values when listeners handle the redispatched event.
If you do not override the clone() method, Flash Player will call the clone() method defined in the superclass and cause the type coercion error I described above.
Below is a sample class with the clone() method overridden correctly:
package com.fm.mmc
{
import flash.events.Event;
public class MMCEvent extends Event
{
private var _eventMessage:String;
public static const ERROR:String = "error";
public static const COMPLETE:String = "complete";
public function MMCEvent(type:String, msg:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
_eventMessage = msg;
}
public function get eventMessage():String
{
return _eventMessage;
}
override public function clone():Event
{
return new MMCEvent(type, _eventMessage);
}
}
}