サイトトップ

Director Flash 書籍 業務内容 プロフィール

Flash OOP Japan Seminar
ActionScript 2.0について

*サンプルデータのソースFLAファイルを開くにはFlash MX 2004、外部ASファイルには同Professional版あるいはエディタが必要です。

1. 厳密な型指定
代入式は、両辺の変数に型指定が必要。タイムライン上のスクリプト(フレームアクションやMovieClipアクションなど)は、クラス定義ファイルと異なった扱いがなされる(スクリプト001)。

スクリプト001■コンパイルエラーの発生しないスクリプト

// _root // フレームアクション
var my0_str = 1;  // 接尾辞は型指定と無関係
var my1_str:String = my0_str;  // 右辺の値が型指定なし
function returnNumber():Number {
  var _str = "returning value";
  return _str;  // 型指定のない変数値を返している
}
var n0:Number = returnNumber();  // 関数の戻り値はNumber型で指定されている
var n1:Number = this;  // タイムライン上のthisは型指定されない
var n2:Number = this.my1_str;  // 型指定のないインスタンスのプロパティは型を調べない
var n3:Number = _root.my1_str;  // タイムライン上の変数を検索して型を調べることはない

2. 定義済み(ビルトイン)クラスの継承
ActionScript 2.0では、定義済みクラスを継承して、メソッドを拡張する(スクリプト003)。

スクリプト002■実行例

// フレームアクション
var _str:MyString = new MyString("microsoft");  // new演算子でコンストラクタ関数を呼出す
trace(_str.replace("s", "$"));  // 出力: micro$oft


スクリプト003■Stringクラスを継承したActionScript 2.0クラス定義(MyString.zip/約4KB)

// ActionScript 2.0クラス定義ファイル: MyString.as
class MyString extends String {  // Stringクラスを継承
  function MyString(_str:String) {  // コンストラクタ関数定義
    super(_str);スーパークラスに引数を渡して初期化
  }
  // メソッドreplace()定義
  // [引数]from_str: 検索文字列/to_str: 置換文字列
  // [戻り値]置換後の文字列
  function replace(from_str:String, to_str:String):String {
    return this.split(from_str).join(to_str);
  }
}

Flash MX 2004(Flash Player 7書出し)では、定義済みのクラスに存在しないプロパティやメソッドにアクセスすると、コンパイルエラーを発生する(ダイナミックなクラスObjectやMovieClipクラスは除く)。

スクリプト004■Stringクラスに直接メソッドを追加するとコンパイルエラー(Flash Player 7書出し時)

String.prototype.replace2 =
function(from_str:String, to_str:String):String {  // prototypeプロパティへの定義はエラーなし
  return this.split(from_str).join(to_str);
};
var _str:String = "microsoft";
_str = _str.replace2("s", "$");  // 定義済みクラスにないメソッドへのアクセスはコンパイルエラー
// _str = _str["replace2"]("s", "$");  // 配列(ブラケット)アクセスならエラーなし

グローバルクラスパスのclassesフォルダ([ActionScriptリファレンスガイド] > [ActionScript 2.0によるクラスの作成] > [クラスパスについて] > [グローバルなクラスパスとドキュメントレベルのクラスパス]参照)には、型チェックのためのintrinsicクラスファイルが格納されている(スクリプト005)。intrinsicクラスは、コンパイラが型チェックをするためのプロパティやメソッドの型定義のみされているクラス。

スクリプト005■型チェックのために用意されたintrinsicクラス

//****************************************************************************
// ActionScript Standard Library
// String object
//****************************************************************************

intrinsic class String
{
  function String(string:String);
  function valueOf():String;
  function toString():String;
  function toUpperCase():String;
  function toLowerCase():String;
  function charAt(index:Number):String;
  function charCodeAt(index:Number):Number;
  function concat():String;
  function indexOf(value:String, startIndex:Number):Number;
  function lastIndexOf(value:String, startIndex:Number):Number;
  function slice(index1:Number,index2:Number):String;
  function substring(index1:Number,index2:Number):String;
  function split(delimiter:String):Array;
  function substr(index1:Number,index2:Number):String;
  static function fromCharCode():String;
  var length:Number;
}

MovieClipLoaderクラスのintrinsicクラスには、onLoadInitメソッドの定義が漏れている。「MovieClipLoader.onLoadInitメソッドでエラーが発生する」参照。

3. 静的(static)メンバの継承(Math.zip/約12KB)
静的(static)なメンバ(プロパティおよびメソッド)も、継承は可能(スクリプト006)。

スクリプト006■Mathクラスを継承したクラス定義

// ActionScript 2.0クラス定義ファイル: MyMath.as
class MyMath extends Math {  // Mathクラスを継承
  // 静的(static)プロパティ宣言
  static var radianToDegree:Number = 180/PI;  // PIをスーパークラスから参照
  // 静的(static)メソッドradiansToDegrees()定義
  // [引数]radian: ラジアン値
  // [戻り値]度数値
  static function radiansToDegrees(radian:Number):Number {
    return radian*radianToDegree;
  }
}

タイムラインからは、1度スーパークラスを参照しないと、サブクラスが継承しているスーパークラスの静的(static)メンバを参照できない(スクリプト007)。とくにコンパイルエラーは発生しない。

スクリプト007■スーパークラスを参照しておかないとサブクラスからスーパークラスのメソッドが使えない

// MovieClip: マウスポインタの方向に回転するインスタンス
// 第1フレームアクション
// Math;  // スーパークラスへのアクセスが必要
this.onEnterFrame = function() {
  var radian:Number = MyMath.atan2(_ymouse, _xmouse);  // スーパークラスの静的(static)メソッドを参照できない
  _rotation += MyMath.radiansToDegrees(radian)*0.2;
};

他のクラス定義の本文から参照すれば、問題ない(スクリプト008)。

スクリプト008■サブクラスの継承した静的(static)メソッドをActionScript 2.0クラスから呼出す

// ActionScript 2.0クラス定義ファイル: Rotation.as
class Rotation extends MovieClip {
  function onEnterFrame():Void {
    // サブクラスからスーパークラスの静的(static)メソッドにアクセス
    var radian:Number = MyMath.atan2(_ymouse, _xmouse);
    _rotation += MyMath.radiansToDegrees(radian)*0.2;
  }
}

図001■ActionScript 2.0クラスをMovieClipシンボルに設定

4. Arrayクラスの問題
Arrayクラスのメソッドには、戻り値がObject型で指定されているものがある(スクリプト009)。他のデータ型に指定した変数に代入する場合は、キャストする必要がある(スクリプト010)。

スクリプト009■intrinsicクラスArray.asにおけるpop()メソッドの定義

//****************************************************************************
// ActionScript Standard Library
// Array object
//****************************************************************************

intrinsic dynamic class Array
{
  // ...[中略]...
  function pop():Object;
  // ...[後略]...
}


スクリプト010■Array.pop()メソッドの戻り値はObject型なのでキャストが必要

// フレームアクション
var _str:String = "test";
var _array:Array = new Array();
_array.push(_str);
// var test_str:String = _array.pop();  // コンパイルエラー
var test_str:String = String(_array.pop());  // キャストが必要

しかし、Arrayでキャストすることができない(スクリプト011)。Array()関数が呼出されてしまう。

スクリプト011■Array()はキャストの機能を果たさない

// フレームアクション
var my_array:Array = ["test"];
var _array:Array = new Array();
_array.push(my_array);
var test_array:Array = Array(_array.pop());  // キャストの機能を果たさない
delete my_array;

引数値をエレメントとする配列が作成されてしまう(出力001)。

出力001■[変数のリストアップ]による出力の一部

変数 _level0.test_array = [オブジェクト #2, クラス 'Array'] [
     0:[オブジェクト #3, クラス 'Array'] [
       0:"test"
     ]
   ]

Arrayを継承したクラスでは、Arrayと同様に任意の数の引数や複数のシンタックスを可能にしようとすると、工夫が必要。Flashcodersの「Array constructor」のスレッドを参照。

5. クラス内で定義済みグローバル関数と同名のfunctionを呼出す(UseKeywordAsMethod.zip/約8KB)
クラス内からActionScriptの定義済みグローバル関数と同名のfunctionを呼出そうとしても呼出せない(スクリプト012)。クラス内からであっても、グローバル関数が優先して実行される。ローカル変数に定義した名前のない関数も、呼出すことができない。

this参照を加えれば、メソッドを呼出すことができる。また、MovieClipクラスを継承すると、this参照がなくてもメソッドが呼出せる。しかし、この場合も、ローカル関数は呼出すことができない(バグと考えられる)。

スクリプト012■グローバル関数と同名のfunctionを呼出す

// ActionScript 2.0クラス定義ファイル: UseKeywordAsMethod.as
class UseKeywordAsMethod { // extends MovieClip {  // MovieClipを継承すればthisなしでもメソッドが呼出せる
  function UseKeywordAsMethod() {
    // ローカル関数は呼出せない(MovieClipを継承しても同様)
    // var play = function () {trace("The inner function is called");};
    play();  // グローバル関数が呼出される
    // this.play();  // this参照を加えればメソッドが呼出される
  }
  function play() {
    trace("The play method is called!");
  }
}

_____

作成者: 野中文雄
作成日: 2004年6月19日


Copyright © 2001-2006 Fumio Nonaka.  All rights reserved.