3.0DisplayObjectはEventDispatcherクラスを継承します。したがって、タイムラインに表示するクラスは、イベントリスナーの登録・削除を始め、イベントの配信もできます。独自のイベントをカスタムイベントクラスで定めれば、リスナーに渡す情報が自由に選べます。3.0開発ガイド]/[コアActionScriptクラス]/[イベント処理]/[イベントオブジェクト]で「Eventクラスのサブクラス」の項を見るとつぎのように説明されています。Eventサブクラスを作成する場合は、clone()とtoString()メソッドをオーバーライドして、サブクラスに固有の機能を提供する必要があります。ところが、多くの場合これらのメソッドを再定義(オーバーライド)しなくても、とくに不都合は生じません。本ノートでは、このふたつのメソッドをなぜ定めなければならないのか、また定めないと何が起こるのかをご説明します。Event.clone()メソッドがいつ必要かまずは、Event.clone()メソッドです。[ヘルプ]の説明には、「Eventサブクラスのインスタンスを複製」するメソッドだとされています。このメソッドは、通常とくに呼出す必要はありません。一度配信したイベントオブジェクトを再び配信すると、内部的に呼出されるメソッドだからです。そこで、テスト用にEventのサブクラス(MyEvent)を定義してみましょう(スクリプト001)。スーパークラスEventのコンストラクタメソッドには、必ずイベント名の文字列を渡さなければなりません(第7行目)。スーパークラスのコンストラクタメソッドはsuperステートメントで呼出します。イベント名の文字列は静的定数(TEST)として定めました(第4行目)。このクラス独自のプロパティ(date)をひとつ宣言し(第5行目)、コンストラクタで初期値を与えています(第8行目)。Date();}}}このカスタムイベントMyEventのインスタンスを、同じ場所に保存したムービー(FLA)ファイルのフレームアクションで配信します(スクリプト002)。リスナー関数(traceEvent)も同じフレームアクションに定め(第9〜11行目)、カスタムイベント定数(MyEvent.TEST)で登録しました(第2行目)。イベントはEventDispatcher.dispatchEvent()メソッドにイベントオブジェクトを渡して配信します(第6〜7行目)。確認用}スクリプト002でイベントを配信するテスト用の関数(testEvent())は2度呼出しています。したがって、リスナー関数(traceEvent())は確認のためのイベントオブジェクトを2回[出力]します(図001)。エラーなどの問題はとくに生じません。図001■イベントを配信する関数は2度呼出すスクリプト002を少し書替えます(スクリプト003)。イベントオブジェクトを関数内のローカル変数に入れず、タイムライン変数に予め納めておきます(第6行目を第1行目で替えます)。すると、テスト用の関数(testEvent())は呼ばれるたびにイベントオブジェクトをつくるのでなく、毎回同じオブジェクトを配信することになります。{trace(eventObject);}[ムービープレビュー]を確かめると、「強制型変換に失敗しました」というランタイムエラー#1034が示されます(図002)。見ると、1行目の[出力]は前掲スクリプト002と同じです(前掲図001下図参照)。エラーを起こしたのは、イベントの2回目の配信(スクリプト003第4行目)なのです。図002■強制型変換に失敗したというランタイムエラーが示される新たにつくったイベントオブジェクトは、1度しか配信できません。送ったイベントオブジェクトをEventDispatcher.dispatchEvent()メソッドに渡すと、内部的にEvent.clone()メソッドが呼出され、戻り値の複製されたイベントオブジェクトを配信します。ところが、継承したEvent.clone()メソッドでは、サブクラスのオブジェクトは複製できません。複製されたスーパークラスEventのオブジェクトは、サブクラスのインスタンスとしては扱えないというのがランタイムエラーの意味することです(前掲図002下図)。Event.clone()メソッドをオーバーライドするそこで、サブクラスのインスタンスを複製するように、サブクラス独自のclone()メソッドを定めなければなりません。スーパークラスに備わっているメソッドをサブクラスで定義し直すことは「オーバーライド」と呼ばれます。オーバーライドするメソッドにはoverride属性キーワードを添え、メソッド名のほかアクセス制御の属性ならびに引数とそのデータ型および戻り値のデータ型をすべてスーパークラスと同じにしなければなりません。カスタムイベントクラス(MyEvent)にclone()メソッドを再定義したのが以下のスクリプト004です(第10〜15行目)。コンストラクタメソッドで新規のオブジェクトをつくったうえで、ただひとつの独自プロパティ(date)をコピーして返しています。呼出されたことが確かめられるようにtrace()関数を加えておきました。eventObject;}}}前掲スクリプト003のフレームアクションはそのままで[ムービープレビュー]を試すと、エラーは出なくなります。[出力]パネルの2行目にDateオブジェクト()の文字列が表れるのは、オーバーライドしたclone()メソッドのtrace()結果で、2回目の配信でこのメソッドが呼ばれたことを示します(図003)。図003■イベントオブジェクトの2回目の配信でclone()メソッドが呼出されるこれでイベントオブジェクトを使い回しても、2度目以降は再定義したclone()メソッドがオブジェクトを複製して、エラーなく配信が行われます。Event.toString()メソッドをオーバーライドするEvent.toString()メソッドは、オーバーライドしないからといってことさら問題は起こりません。このメソッドは、インスタンスの文字列表現(String型)を返します。インスタンスの文字列表現を確かめたいおもな場合のひとつが、trace()関数による[出力]です。KeyboardEventやMouseEventクラスのイベントオブジェクトを[出力]すると、つぎのようにクラスに応じたオブジェクトの情報が得られます。delta=0]Event.toString()メソッドが返す文字列の構成は、つぎのようにクラス名とイベント名から始まり、オブジェクトのプロパティとその値が続きます[*1]。...]ところが、前掲スクリプト004のクラスMyEventは、Event.toString()メソッドをオーバーライドしていません。そのため、スーパークラスのEvent.toString()メソッドが呼出されて、イベント名("test")を除いて通常(Event.ENTER_FRAMEなど)のEventインスタンスとまったく同じ内容になっています。eventPhase=2]文字列表現のクラス名を正しく直し、クラス独自のプロパティ(date)も情報に加えたいところです。カスタムクラス(MyEvent)にtoString()メソッドを再定義しましょう。このときぜひ覚えておきたいメソッドがEvent.formatToString()です。toString()メソッドが返す文字列をつくるのに、Stringクラスのメソッドでプロパティ名や値をひとつひとつつなぎ合わせる必要はありません。Event.formatToString()メソッドの引数に、戻り値として加えたいプロパティ名の文字列をただ並べて渡せばよいのです。プロパティ名)カスタムイベントクラス(MyEvent)にtoStringメソッドを再定義したのが、つぎのスクリプト005です[*2]。return_str;}}}前掲スクリプト003のフレームアクションで[ムービープレビュー]を確かめると、クラス名はカスタムクラスMyEventに変わり、独自のプロパティdateが[出力]に加わっています(図004)。toString()メソッドの戻り値は前述Event.formatToString()でつくりました(スクリプト005第17行目)。イベント名の文字列を示すEvent.typeもEventクラスのプロパティのひとつです。イベントクラスには読取り専用のプロパティが少なくありません。他方、他のクラスやフレームアクションからのアクセスを許すため、public属性で定めることになります。したがって、get/setアクセサメソッドとするのが確実でしょう。