CodeZine(コードジン)

特集ページ一覧

JavaとActionScript 3の違い:属性操作編

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/11/08 14:00

目次

属性名を使ったアクセス

 Javaでは、フィールドへのアクセスには、「ドット(.)+フィールド名」を使います。

public class Foo
{
  public int bar;
}
 
Foo foo = new Foo();
foo.bar = 1;

 既に見てきたように、AS3の属性へのアクセスも、同様のシンタックスを使います。しかし、AS3にはもう1つ、属性名の文字列を使って、属性にアクセスするという方法も用意されています。

public class Foo {
  public var bar:int;
}
 
var foo:Foo = new Foo();
// 以下は同じ意味
foo.bar = 1;
foo["bar"] = 1;

 このサンプルのように、オブジェクト名に続いて[]内に属性名を記述します。属性名には変数を使うこともできます。

var foo:Foo = new Foo();
var name:String = "bar";
foo[name] = 1;

リフレクション(属性)

 Javaも、リフレクションの機能を使うと文字列を使ってフィールドにアクセスすることができます。

Class c = foo.getClass();
String name = "bar";
Field f = c.getField(name);
f.set(foo, 1);

 このように、リフレクションを利用すると実行時にアクセスするフィールドを選択できるため、より柔軟性の高いコードを記述できます。しかし、通常の記述に比べてコードが複雑で読みにくくなってしまうことなどにより、リフレクションの使用はあまり一般的ではありません。

 一方、上で触れたように、AS3では同様の記述が1行で済みます。Javaのようにはコードの保守性を損なわないため、実行時にアクセスするフィールドを選択する、という記述が使いやすくなっています。

foo[name] = 1;

存在しない属性へのアクセス

 Javaでフィールドに直接アクセスする場合、存在しないフィールド名を指定すると、コンパイルエラーになります。

public class Foo {}
 
Foo foo = new Foo();
foo.bar = 1;
// Foo にはフィールドが無いため、コンパイルエラーになる

 これは、AS3でも同じです。

public class Foo {}
 
var foo:Foo = new Foo();
foo.bar = 1;
// Foo には属性が無いため、コンパイルエラーになる

 しかし、属性名を使って、属性にアクセスする場合、コンパイル時にフィールドの有無のチェックが行われません。存在しない属性名が指定された場合は、ランタイムエラーになります。

var foo:Foo = new Foo();
foo["bar"] = 1;
// Foo にはフィールドが無いため、ランタイムエラーになる

Map

Object

 Javaでは、コレクションフレームワークにMapが含まれます。Mapは指定された型のオブジェクトをキーとして値を管理する機能を提供します。例えば、下はStringをキーとするHashMapを使って、String型の値を管理する例です。

HashMap<String,String> map = new HashMap<String,String>();
String bar = "bar";
map.put("foo", bar)
 
// "foo"に対応する値を取得する
Object value = map.get("foo"); 

 AS3では、ObjectMapの機能を持っています。キーとして使えるオブジェクトはStringに限定されます。一方、値は任意の型になります。

var obj:Object = new Object();
var bar:String = "bar";
obj["foo"] = bar;
 
// "foo"に対応する値を取得する
var value:Object = obj["foo"];

 ところで、上のサンプル内の記述方法は、クラスの属性にアクセスする場合と同じ["属性名"]です。通常のクラスでは、属性名で指定した属性が存在しなければ、ランタイムエラーになります。しかし、Objectの場合は、任意の名前の指定が可能です。このことから、Objectは、実行時に属性を追加することができるクラス、と考えることもできます。

 Objectから、存在しないキーを指定して値を参照すると、undefinedが返されます。通常のクラスであればランタイムエラーが発生しているところです。

var obj:Object = new Object();
trace(obj["foo"]);
// undefined が出力される

 さらに、Objectの場合は下のような記述をしても、コンパイルエラーは発生しません。

var obj:Object = new Object();
trace(obj.foo);
// undefined が出力される

 ところで、AS3のObjectのインスタンスを初期化するのに、下のような書き方もできます。コロン(:)の前が要素名、後が要素の値です。要素間はカンマ(,)で区切ります。見た目にもMapの初期化っぽく見えます。

var obj:Object = { foo:10, bar:"Hello" };

Dictionary

 AS3で任意のオブジェクトをキーとしてMapを使いたい場合、Dictionaryクラスを使います。

var map:Dictionary = new Dictionary();
var foo:Object = new Object();
map[foo] = "foo";
 
var value:Object = map[foo]; 

 Dictionaryのキーは、値ではなくインスタンス自体です。同じ値をもつ同じ型のインスタンスでも、違うキーとして認識されます。下の例は、2つのObjectのインスタンスを使って、Dictionaryから値を取得しています。

var map:Dictionary = new Dictionary();
var foo:Object = new Object();
var bar:Object = new Object();
map[foo] = "foo";
 
trace(map[foo]); // fooが出力される
trace(map[bar]); // undefinedが出力される

 Dictionaryの詳細はASDocのDictionaryをご覧ください。

Array

 AS3のArrayは数値をキーとしたMapのような動作をします。これは、JavaのArrayと大きく異なる点です。

 例えば、Javaでは配列の大きさがインスタンス生成時に決まります。

Array arr = new Array(1);
arr[0] = new Object();
arr[1] = new Object();
// ランタイムエラーが発生

 AS3では、任意のキーを指定できます。

var arr:Array = [];
arr[0] = new Object();
arr[10] = new Object();
// 10番目の要素が追加される

  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:Adobe Developer Connection

もっと読む

著者プロフィール

  • 上条 晃宏(カミジョウ アキヒロ)

    アドビにてFlashプラットフォーム上のユーザー体験やアーキテクチャデザインのコンサルティングを担当、数多くのFlash/Flexプロジェクトに携わる。

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5