Flash CS3 ドキュメンテーション |
|||
| ActionScript 3.0 のプログラミング > ActionScript 言語とシンタックス > データ型 > 型チェック | |||
型チェックは、コンパイル時または実行時のいずれかの時点で行われます。C++ や Java のような型指定を静的に行う言語では、コンパイル時に型チェックを行います。Smalltalk や Python のような型指定を動的に行う言語では、実行時に型チェックを行います。ActionScript 3.0 は型指定を動的に行う言語なので、実行時に型チェックが行われますが、"strict モード" と呼ばれる特別なコンパイラモードでのコンパイル時型チェックもサポートされています。strict モードでは、型チェックはコンパイル時と実行時の両方で行われますが、standard モードでは、型チェックは実行時にのみ行われます。
型指定を動的に行う言語では、コードを非常に柔軟に構成できる反面、型指定エラーが実行時に明らかになるという難点があります。型指定を静的に行う言語では、コンパイル時に型指定エラーが報告されますが、コンパイル時に型情報が分かっている必要があるという難点があります。
コンパイル時の型チェックは、大規模なプロジェクトでよく利用されます。プロジェクトの規模が拡大するにつれて、通常はデータ型の柔軟性よりできるだけ早い時点で型指定エラーを把握する方が重要になるためです。これは、デフォルトで Adobe Flash CS3 と Adobe Flex Builder 2 の ActionScript コンパイラが strict モードで実行するように設定されているからです。
コンパイル時に型チェックを行うためには、コンパイラがコード内の変数または式のデータ型情報を分かっている必要があります。変数のデータ型を明示的に宣言するには、変数名の接尾辞としてコロン演算子 (:) とその後ろにデータ型を追加します。データ型をパラメータに関連付けるには、コロン演算子の後ろにデータ型を使用します。たとえば、次のコードは xParam パラメータにデータ型の情報を追加し、変数 myParam を明示的なデータ型で宣言します。
function runtimeTest(xParam:String)
{
trace(xParam);
}
var myParam:String = "hello";
runtimeTest(myParam);
strict モードでは、ActionScript コンパイラは、型の不一致をコンパイルエラーとしてレポートします。たとえば、次のコードは、Object 型の関数パラメータ xParam を宣言した後で、このパラメータに String 型と Number 型の値を割り当てようとします。これは、strict モードでコンパイルエラーを発生します。
function dynamicTest(xParam:Object)
{
if (xParam is String)
{
var myStr:String = xParam; // strict モードでのコンパイルエラー
trace("String: " + myStr);
}
else if (xParam is Number)
{
var myNum:Number = xParam; // strict モードでのコンパイルエラー
trace("Number: " + myNum);
}
}
ただし、strict モードの場合でも、型指定されていない代入ステートメントの右側をそのままにして、コンパイル時の型チェックを行わないように選択できます。変数または式に型指定なしとマークするには、型注釈を省略するか、特別なアスタリスク (*) 型注釈を使用します。たとえば、上記の例で、型注釈を使用しないように xParam パラメータを変更して、strict モードでコードをコンパイルします。
function dynamicTest(xParam)
{
if (xParam is String)
{
var myStr:String = xParam;
trace("String: " + myStr);
}
else if (xParam is Number)
{
var myNum:Number = xParam;
trace("Number: " + myNum);
}
}
dynamicTest(100)
dynamicTest("one hundred");
ActionScript 3.0 では、実行時の型チェックは、strict モードと standard モードのいずれでコンパイルされるかに関係なく行われます。配列を必要とする関数に値 3 がパラメータとして渡されるとします。strict モードでは、値 3 は Array データ型と互換性がないため、コンパイラはエラーを生成します。strict モードを無効にし、standard モードで実行すると、コンパイラは型の不一致について報告しませんが、Flash Player による実行時の型チェックではライタイムエラーになります。
次の例では、Array 引数を必要とするにもかかわらず、値 3 が渡される typeTest() という名前の関数を示します。この場合、値 3 はパラメータで宣言されたデータ型 (Array) のメンバーではないので、standard モードでランタイムエラーが発生します。
function typeTest(xParam:Array)
{
trace(xParam);
}
var myNum:Number = 3;
typeTest(myNum);
// ActionScript 3.0 standard モードでのランタイムエラー
strict モードで操作しているときでも、実行時の型指定エラーが発生する場合もあります。これは strict モードを使用しているときに、型指定されていない変数を使用してコンパイル時の型チェックをしないようにしている場合に発生します。型指定されていない変数を使用すると、型チェックは省略されるのではなく、実行時まで保留されます。たとえば、上記の例の myNum 変数に宣言したデータ型が存在しない場合、コンパイラは型の不一致を検出できません。ただし、Flash Player は、代入ステートメントの結果として 3 に設定された実行時の値 myNum を Array データ型に設定された xParam の型と比較するので、ランタイムエラーを生成します。
function typeTest(xParam:Array)
{
trace(xParam);
}
var myNum = 3;
typeTest(myNum);
// ActionScript 3.0 のランタイムエラー
実行時に型チェックを行うと、コンパイル時に型チェックを行うより継承を柔軟に使用することができます。standard モードでは、型チェックを実行時まで保留することで、"アップキャスト" する場合でもサブクラスのプロパティを参照できます。アップキャストは、基本クラスを使用してクラスインスタンスの型を宣言し、クラスのインスタンス化にサブクラスを使用するときに行われます。たとえば、拡張可能な ClassBase という名前のクラスを作成することができます (final 属性を持つクラスは拡張できません)。
class ClassBase
{
}
続いて、次のように someString という名前の 1 つのプロパティを持つ ClassExtender という名前の ClassBase のサブクラスを作成することができます。
class ClassExtender extends ClassBase
{
var someString:String;
}
両方のクラスを使用して、ClassBase データ型を使用して宣言されているが、ClassExtender コンストラクタを使用してインスタンス化されているクラスインスタンスを作成することができます。基本クラスにはサブクラスにないプロパティやメソッドは含まれないので、アップキャストは安全な操作と考えられています。
var myClass:ClassBase = new ClassExtender();
ただし、サブクラスには、その基本クラスに含まれないプロパティまたはメソッドが含まれます。たとえば、ClassExtender クラスには someString プロパティが含まれますが、このプロパティは ClassBase クラスには含まれません。ActionScript 3.0 の standard モードでは、次の例に示すように、myClass インスタンスを使用してコンパイル時エラーを生成せずにこのプロパティを参照することができます。
var myClass:ClassBase = new ClassExtender(); myClass.someString = "hello"; // ActionScript 3.0 standard モードでのエラーなし
ActionScript 3.0 で新しく導入された is 演算子を使用すると、変数または式が特定のデータ型のメンバーであるかどうかをテストすることができます。旧バージョンの ActionScript では instanceof 演算子に同じ機能がありましたが、ActionScript 3.0 では instanceof 演算子はデータ型のメンバーシップのテストに使用しません。手動による型チェックでは、instanceof 演算子の代わりに is 演算子を使用する必要があります。これは、式 x instanceof y は、x のプロトタイプチェーンに y があるかどうかをチェックするだけであるため、また ActionScript 3.0 では、プロトタイプチェーンで継承階層全体を確認できないためです。
is 演算子は、適切な継承階層を調べます。また、オブジェクトが特定のクラスのインスタンスであるかどうかだけではなく、特定のインターフェイスを実装するクラスのインスタンスであるかどうかも調べるために使用することができます。次の例では、Sprite クラス mySprite のインスタンスを作成し、is 演算子を使用して mySprite が Sprite クラスおよび DisplayObject クラスのインスタンスであるかどうか、および IEventDispatcher インターフェイスを実装しているかどうかをテストします。
var mySprite:Sprite = new Sprite(); trace(mySprite is Sprite); // true trace(mySprite is DisplayObject); // true trace(mySprite is IEventDispatcher); // true
is 演算子は、継承階層を調べて、mySprite が Sprite クラスおよび DisplayObject クラスと互換性があることを適切に報告します。ただし、Sprite クラスは DisplayObject クラスのサブクラスです。is 演算子は、mySprite が IEventDispatcher インターフェイスを実装するクラスを継承するかどうかも調べます。Sprite クラスは、IEventDispatcher インターフェイスを実装する EventDispatcher クラスを継承するため、is 演算子は、mySprite が同じインターフェイスを実装することを正しく報告します。
次の例は、前の例と同じテストを示していますが、is 演算子の代わりに instanceof 演算子を使用しています。instanceof 演算子は mySprite が Sprite または DisplayObject のインスタンスであることを正しく識別しますが、mySprite が IEventDispatcher インターフェイスを実装しているかどうかをテストするのに使用すると false を返します。
trace(mySprite instanceof Sprite); // true trace(mySprite instanceof DisplayObject); // true trace(mySprite instanceof IEventDispatcher); // false
ActionScript 3.0 で新しく追加された as 演算子を使用しても、式が指定されたデータ型のメンバーであるかどうかをチェックすることができます。しかし、is 演算子とは異なり、as 演算子はブール値を返しません。as 演算子は、true の代わりに式の値、false の代わりに null を返します。次の例は、Sprite インスタンスが DisplayObject、IEventDispatcher、および Number データ型のメンバーであるかどうかをチェックする場合に、is 演算子の代わりに as 演算子を使用した結果を示します。
var mySprite:Sprite = new Sprite(); trace(mySprite as Sprite); // [object Sprite] trace(mySprite as DisplayObject); // [object Sprite] trace(mySprite as IEventDispatcher); // [object Sprite] trace(mySprite as Number); // null
as 演算子を使用する場合、右側のオペランドはデータ型である必要があります。右側のオペランドにデータ型ではなく式を使用しようとすると、エラーになります。
このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート
現在のページ: http://livedocs.adobe.com/flash/9.0_jp/main/00000045.html