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