ActionScript 3.0で始めるオブジェクト指向スクリプティング

第20回戻り値をクラスで定義する

前回の第19回Objectクラスと静的メソッドの定義では、MyTimerクラスに手を加え、getElapsedTime()メソッドがObjectインスタンスを返すようにした図1⁠。今回は、さらに新たなクラスを定義して、MyTimerクラスと組合わせて使ってみたい(前回のサンプルファイルは2ページからダウンロードできる⁠⁠。なお、今回から新発売のFlash CS4 Professionalを用いることにする[1]⁠。

図1 MyTimerクラスの定義
図1 MyTimerクラスの定義

情報を収めるクラスの定義

MyTimerクラスのgetElapsedTime()メソッドが返すObjectインスタンスは、さまざまなプロパティ値が自由に設定できる。しかし反面、その自由さが問題でもある。たとえば、クラス定義(AS)ファイルと同階層に保存したFlashムービー(FLA)ファイルにつぎのようなフレームアクションを記述すれば、getElapsedTime()メソッドの戻り値であるObjectインスタンスにnameという名前のプロパティを設定したり、数値を納めるつもりのプロパティhoursに文字列が代入できてしまう図2⁠。

var myObject:MyTimer = new MyTimer();
var oElapsedTime:Object = myObject.getElapsedTime();
oElapsedTime.name = "fumio";
oElapsedTime.hours = "one o'clock";
図2 Objectインスタンスにはプロパティも値も自由に設定できる
図2 Objectインスタンスにはプロパティも値も自由に設定できる

設定できるプロパティやそのデータ型を指定するには、カスタムクラスを定義すればよい。クラス名はMyTimerInfoとし、数値のインスタンスプロパティとしてhours、minutes、seconds、 millisecondsを宣言する。すると、クラスMyTimerInfoの大枠は、つぎのように定義されよう。なお、各プロパティは整数のint型で指定した。

package {
  public class MyTimerInfo {
    public var milliseconds:int;
    public var seconds:int;
    public var minutes:int;
    public var hours:int;
    public function MyTimerInfo() {
    }
  }
}

このMyTimerInfoクラスのインスタンスには、宣言した以外のプロパティは設定できない図3⁠。また、もちろん代入できる値は、データ型として指定した数値のみだ[2]⁠。

図3 クラスMyTimerInfoに宣言されたプロパティ以外は設定できない
図3 クラスMyTimerInfoに宣言されたプロパティ以外は設定できない

MyTimerクラスからMyTimerInfoクラスを使う

クラスMyTimerInfoには、さらにメソッドも加えたい。しかしその前に、MyTimerクラスのメソッドgetElapsedTime()に修正を加えて、戻り値はObjectでなくMyTimerInfoインスタンスにしておこう(スクリプト1⁠⁠。また、MyTimerInfoクラスに新たに定義するメソッドについても、MyTimerクラスからどのように使いたいのかを先に決めてしまうことにする。

スクリプト1 MyTimerクラスのgetElapsedTime()メソッドはMyTimerInfoインスタンスを返す
// ActionScript 3.0クラス定義ファイル: MyTimer.as
package {
  public class MyTimer {
    private var my_date:Date;
    function MyTimer() {
      resetTimer();
    }
    public function resetTimer():void {
      my_date = new Date();
    }
    public function getElapsedTime():MyTimerInfo {
      var current_date:Date = new Date();
      var nElapsedTime:Number = current_date.time - my_date.time;
      var elapsedTime:MyTimerInfo = new MyTimerInfo(nElapsedTime);
      return elapsedTime;
    }
    /* public static function translateToTimeObject(nTime:Number):Object {   // メソッド削除
    } */
  }
}

第1に、getElapsedTime()メソッドの戻り値とその値を納める変数(elapsedTime)のデータ型は、上述のとおりクラスMyTimerInfoで指定した。

そして第2に、MyTimerInfoインスタンスを生成するコンストラクタメソッドの呼出しに、引数として経過時間のミリ秒数(nElapsedTime)を渡している。これは、MyTimerInfoクラスが渡されたミリ秒数をもとに時分秒ミリ秒の値を計算して、各ブロパティに設定することを想定した。したがって、MyTimerクラスにはそれらの数値を計算するメソッドtranslateToTimeObject()は要らなくなる。

すると、MyTimerInfoクラスは、以下のように修正される(スクリプト2⁠⁠。コンストラクタメソッドがミリ秒数の数値を受取り、それを新たに定義したメソッドsetTime()に渡す。そして、 setTime()メソッドはミリ秒数から時分秒ミリ秒を計算して、各インスタンスプロパティに値を設定するのだ。

setTime()メソッドの処理内容は、基本的にMyTimerクラスに定義されていた静的(static)なメソッドtranslateToTimeObject()と同じなので、とくに説明は要らないだろう[3]⁠。なお、setTime()は静的メソッドでなくインスタンスメソッドとし、private属性を指定した。

スクリプト2 MyTimerInfoクラスのコンストラクタがミリ秒数を受取る
// ActionScript 3.0クラス定義ファイル: MyTimerInfo.as
package {
  public class MyTimerInfo {
    public var milliseconds:int;
    public var seconds:int;
    public var minutes:int;
    public var hours:int;
    public function MyTimerInfo(nMilliseconds:Number=0) {
      setTime(nMilliseconds);
    }
    private function setTime(nTime:Number):void {
      milliseconds = nTime % 1000;
      nTime = Math.floor(nTime / 1000);
      seconds = nTime % 60;
      nTime = Math.floor(nTime / 60);
      minutes = nTime % 60;
      hours = Math.floor(nTime / 60);
    }
  }
}

前回と同じく[4]⁠、Flashムービーファイルにつぎのようなフレームアクションを記述すれば、ステージをクリックするたびに、MyTimerインスタンスを生成してから経過した時分秒ミリ秒が[出力]パネルに表示される図4⁠。

var myObject:MyTimer = new MyTimer();
stage.addEventListener(MouseEvent.CLICK, xTrace);
function xTrace(eventObject:MouseEvent):void {
  var oElapsedTime:MyTimerInfo = myObject.getElapsedTime();
  trace(oElapsedTime.hours);
  trace(oElapsedTime.minutes);
  trace(oElapsedTime.seconds);
  trace(oElapsedTime.milliseconds);
}
図4 クリックすると経過した時分秒ミリ秒が[出力]される
図4 クリックすると経過した時分秒ミリ秒が[出力]される

次回は、MyTimerInfoクラスにさらに手を加えるつもりだ。

今回解説した次のサンプルファイルがダウンロードできます。

おすすめ記事

記事・ニュース一覧