イナヅマTVログ

AS3, EventサブクラスのtoStringとformatToString

| 1件のコメント

ActionScript 3 で Event サブクラスを作りカスタム・イベントを作成するときのメモ。

イベントを複製する clone メソッド作成は必須になります。
サブクラスでoverrideして作らなければいけません。
作らなくともエラーにはなりませんが…

toString メッソドは作っても作らなくても良いような記述がヘルプに書いてあって、長い間釈然としていなかったのですがやっと理解できたような気がします。

オンラインヘルプには以下のように書かれています。
http://help.adobe.com/ja_JP/FlashPlatform/reference/actionscript/3/flash/events/Event.html#formatToString()
formatToStringの説明。

カスタム ActionScript 3.0 Event クラスに toString() メソッドを実装するためのユーティリティ関数です。toString() メソッドをオーバーライドすることは、推奨されますが必須ではありません。

Eventコンストラクタの引数。

Event(type:String, bubbles:Boolean = false, cancelable:Boolean = false)

パラメーター
type:String — Event.type としてアクセス可能なイベントタイプです。

bubbles:Boolean (default = false) — Event オブジェクトがイベントフローのバブリング段階で処理されるかどうかを判断します。デフォルト値は false です。

cancelable:Boolean (default = false) — Event オブジェクトがキャンセル可能かどうかを判断します。デフォルト値は false です

toStringをoverrideする必要ない場合
カスタムイベント・クラスでtype(イベント名称)だけを作りたい場合。

【例】
スピードを変更を通知するイベント・クラス

package {
 
import flash.events.Event;
public class AccelerateEvent extends Event {
	public static const SPEED_UP:String = "speedUp";
	public static const SPEED_DOWN:String = "speedDown";
 
	public function AccelerateEvent( type:String, bubbles:Boolean=true, cancelable:Boolean=false)
	{
		super(type, bubbles, cancelable);
	}
 
	override public function clone():Event
	{
		return new AccelerateEvent(type, bubbles, cancelable);
	}
}
 
}

使い方

addEventListener(AccelerateEvent.SPEED_UP, onSpeedUp);
dispatchEvent(new AccelerateEvent(AccelerateEvent.SPEED_UP));
 
function onSpeedUp (e:AccelerateEvent):void {
	trace(e);
	// [AccelerateEvent type="speedUp" bubbles=true cancelable=false eventPhase=2]
}

toStringメソッドはイベント・インスタンスをtraceするときに使われています。
ここに表示される以上の情報が無い場合は親クラス(Event)のtoStringメソッドで事足りるためわざわざoverrideする必要はありません。

toStringをoverrideする必要がある場合
MouseEventやProgressEventなどのようにEventクラスtoString以上の情報が必要な場合はtoStringをoverrideしなければなりません。

上記例ではスピードをアップするかダウンするかを通知するだけでした。
これに「どれ位」アップするかダウンするかを通知できるように変更します。

package {
 
import flash.events.Event;
public class AccelerateEvent extends Event {
	public static const SPEED_UP:String = "speedUp";
	public static const SPEED_DOWN:String = "speedDown";
 
	private var _speed:Number;
 
	public function AccelerateEvent(speed:Number, type:String, bubbles:Boolean=true, cancelable:Boolean=false)
	{
		_speed = speed;
		super(type, bubbles, cancelable);
	}
 
	override public function clone():Event
	{
		return new AccelerateEvent(_speed, type, bubbles, cancelable);
	}
}
 
}

AccelerateEventは引数にスピードが追加されました。
これに合わせてcloneメソッドも変更しています。

traceした時にspeedの値も出力されると便利です。
toStringメソッドにspeedの値を追加します。

toStringで使用する変数はpublicに読み取りできなくてはいけません。
今回はpublicな読み取り専用(read only)変数にしています。

	public function get speed():Number
	{
		return _speed;
	}

次にtoStringをoverrideします。

	override public function toString():String
	{
		return formatToString("AccelerateEvent", "speed", "type", "bubbles", "cancelable", "eventPhase")
	}

【完成形】

package {
 
import flash.events.Event;
public class AccelerateEvent extends Event {
	public static const SPEED_UP:String = "speedUp";
	public static const SPEED_DOWN:String = "speedDown";
 
	private var _speed:Number;
 
	public function AccelerateEvent(speed:Number, type:String, bubbles:Boolean=true, cancelable:Boolean=false)
	{
		_speed = speed;
		super(type, bubbles, cancelable);
	}
 
	override public function clone():Event
	{
		return new AccelerateEvent(speed, type, bubbles, cancelable);
	}
 
	override public function toString():String
	{
		return formatToString("AccelerateEvent", "speed", "type", "bubbles", "cancelable", "eventPhase")
	}
 
	public function get speed():Number
	{
		return _speed;
	}
}
 
}

使い方

addEventListener(AccelerateEvent.SPEED_UP, onSpeedUp);
dispatchEvent(new AccelerateEvent(1, AccelerateEvent.SPEED_UP));
 
function onSpeedUp (e:AccelerateEvent):void {
	trace(e);
	// [AccelerateEvent speed=1, type="speedUp" bubbles=true cancelable=false eventPhase=2]
	trace(e.speed);// 1
}

formatToStringが出力を整形してくれるのでここに出力させたいプロパティを列挙する。

今回のようにプロパティを追加しそれを出力させたい時にはtoStringoverrideは必須になります。

update

2011-07-13
野中先生が詳細な記事を書かれています。
特にcloneメソッドをoverrideしない時の問題について詳細に解説されています。

Macromedia Flash非公式テクニカルノート
Eventのサブクラスでclone()とtoString()メソッドをオーバーライドする

1件のコメント

  1. >作らなくともエラーにはなりませんが…

    EventDispatcherによってディスパッチされたイベントを再ディスパッチすると、
    EventDispatcherによってcloneメソッドが呼び出されます。

    デフォルトのEventのcloneの実装ではnew Eventをやっていますので、
    Eventのインスタンスが作られますが、
    function hogeHandler(e:HogeEvent)とかあって再ディスパッチすると、
    HogeEventのクローンがEventであるため、キャストエラーになります。

    使い方によっては注意が必要です。

コメントを残す

必須欄は * がついています


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください