akihiro kamijo: June 2006 Archives

« May 2006 | Main | July 2006 »

June 29, 2006

Cairngorm @ Adobe Labs

Flex 2 のアナウンスにあわせて Cairngorm が Adobe Labs にフィーチャーされています。(Cairngorm @ Adobe Labs)あわせて Flex 2 用の Cairngorm もダウンロード可能になっています。(Cairngorm 2 for Flex 2

今後、Cairngorm と Flex2 のベストプラクティスなども投稿されていく予定だそうです。またディスカッションフォーラムでユーザーからのフィードバックもできるようになるようです。

Adobe Labs の Cairngorm のページには”http://www.adobe.com/go/cairngorm”でアクセスできます。

Posted by ackie at 06:08 AM | Comments (0)

Flash 9 Preview 公開です

Flash 9 の Preview 版が Adobe Labs に公開されました。英語版のみになりますが次のページからダウンロードが可能です。(Flash Professional 9 ActionScript 3.0 Preview

リンク先のページタイトルからも分かるように Flash 9 とは言っていますが、Preview の部分は ActionScript 3 のみで、後は Flash 8 Professional と同じです。詳細が(英語の記事で申し訳ないのですが)デベロッパーセンターに公開されています。Exploring the Flash Professional 9 ActionScript 3.0 Preview 日本語での情報はもうちょっとお待ち下さい。

ともあれ、これで Flash でも AS3 を試せるようになりました。是非お使いください。なお、Preview 版を使用するには Flash 8 Professional か Studio 8 のライセンスが必要になりますのでご注意下さい。

Posted by ackie at 05:00 AM | Comments (0)

June 28, 2006

Flash Player 9 リリース

Flash Player 9 がリリースされました。こちらの URL からダウンロードできます。Flash Player ダウンロードセンター

さっそくどうぞお試し下さい。

Posted by ackie at 08:31 AM | Comments (0)

June 16, 2006

継承-その2

継承の話題の続きです。

インスタンスメソッドのオーバーライド

継承したクラスのインスタンスメソッドをオーバーライドするには override キーワードを使います。オーバーライドするメソッドは以下の条件を満たす必要があります。

  • 同じ名前である
  • 同じアクセス修飾子である
  • 同じ数の引数を持つ
  • 個々の引数の型が同じである
  • 戻り値の型が同じである

final キーワード付で宣言されたメソッドはオーバーライドできません。

また、private 属性のクラスと同じ名前のメソッドを定義する場合は override を付けません。親クラスの private なメソッドは「見えない」からです。

public class MyBase
{
  final public function finalFunc():void {
  }
  public function publicFunc():void {
  }
  private function privateFunc():void {
  }
}

この場合、MyBase クラスの中でオーバーライドできるメソッドは一つだけです。

public class MySub extends MyBase
{
  // final キーワードが付いているためオーバーライドできない
  override public function finalFunc():void {
  }
  // オーバーライド可能
  override public function publicFunc():void {
  }
  // override を付けずに宣言することは可能
  override private function privateFunc():void {
  }
}

super

関数をオーバーロードする際、継承元クラスのメソッドを参照するには super を使います。super.methodName() のような形で使います。

コンストラクタでは super() で親クラスのコンストラクタを参照します。

public class MySub extends MyBase
{
  // コンストラクタ定義
   public function MySub() {
    super();
  }
  // 関数をオーバーロード
  override public function publicFunc():void {
    super.publicFunc();
  }
}

プロパティのオーバーライド

AS3 では属性をオーバーライドをすることができません。

ですが、get や set を使ったプロパティは関数でアクセスするためオーバーライドが可能です。例えば、以下のような定義のクラスがあるとします。

public class MyBase
{
  private var _myProp:String = "myprop";
 
  public function get myProp():String {
    return _myProp;
  }
  public function set myProp(val:String):void {
    _myProp = val;
  }
}

これを継承したクラスでは以下のような記述をすることができます。

public class MySub extends MyBase
{
  override public function get myProp():String {
    return super.myProp;
  }
  override public function set myProp(val:String):void {
    super.myProp = val;
  }
}

Posted by ackie at 07:36 PM | Comments (0)

June 15, 2006

継承

おくればせながら、継承に関する話題を少しまとめます。

extends

サブクラスを定義するには extends キーワードを使います。

// 親クラスの定義
public class MyBase 
{
  public function hello():String {
    return "hello";
  }
}
// サブクラスの定義
public class MySub extends MyBase
{
}

サブクラスのオブジェクトは親クラスのオブジェクトと同様に使うことができます。

// MyBase 型の変数に代入
var base:MyBase = new MyBase();
var sub:MyBase = new MySub();
// MyBase 型の引数を持つ関数にわたす
needBase(sub);
needBase(base);
 
public function needBase(obj:MyBase):void {
  trace(obj.hello());
}

逆に親クラスはサブクラスの代わりにはなりません、が、下のコードは -strict オプションを付けなければ実行できます。

var sub:MyBase = new MySub();
needSub(sub);
 
public function needSub(obj:MySub):void {
  trace(obj.hello());
}

アクセス制限

プロパティの宣言に private を指定すると、他のクラスからは参照できなくなります。また、public を指定した場合は、どのクラスからも参照できます。

protected を指定したプロパティは、継承したクラスからは参照ができます。デフォルトである internal の場合は、同じパッケージ内のクラスであれば参照できます。

少し注意が必要なのは、protected の場合、他のパッケージのクラスであってもサブクラスであれば参照可能なことです。逆に、protected のプロパティは同じパッケージ内のクラスでもサブクラスでなければ参照できません。

また、internal のプロパティは同じパッケージ内のサブクラスのみにしか継承されません。

ちょっと例を見てみましょう。まず、foo というパッケージに FooBase クラスを定義します。クラス内には protected と internal の2種類の関数を定義します。

package foo
{
  public class FooBase
  {
    protected function protectedFunc():void {
    }
    internal function internalFunc():void {
    }
  }
}

次に、bar というパッケージに上記の FooBase のサブクラスを定義します。関数をオーバーライドするため override キーワードを使っています。

package bar
{
  import foo.FooBase;
  
  public class BarSub extends FooBase
  {
    // 親クラスの定義をオーバーライド
    override protected function protectedFunc():void {
    }
    // こっちはオーバーライドできないはず
    override internal function internalFunc():void {
    }
  }
}

これをコンパイルしてみると、protectedFunc() は通りますが、internalFunc() の方はそんな関数は見つからないといわれてしまいます。

また、サブクラス内のコードで、直接親クラスの protected プロパティを参照することはできません。

public class BarSub extends FooBase
{
  public function callProtected():void {
    var foo:FooBase = new FooBase();
    // protected のメソッドを呼び出してみる
    foo.protectedFunc();
  }
}

上記の例の場合、callProtected() が呼ばれるとエラーが発生します。

Posted by ackie at 06:10 PM | Comments (0)

June 07, 2006

URI のエンコードとデコード

引き続きエンコード関連の関数を紹介します。今回は URI をエンコードするための関数です。

encodeURI() 関数と decodeURI() 関数

encodeURI() 関数 (livedocs@lab) は URI 文字列を UTF-8 値にエンコードします。英数字は変換の対象外ですが、他にも URI の一部として使われる記号は変換されません。

var str:String = "http://w.c/a?b+ま&";
trace(encodeURI(str)); // http://w.c/a?b+%E3%81%BE& が出力される

この例では「ま」だけが変換されていますが、/ 等の文字は変換されていませんね。

encodeURI() によって変換されない記号は以下のものがあります。上段は URI の区切り文字として使用される記号です。

; / ? : @ & = + $ , # 
- _ . ! ~ ' ( )

encodeURI() でエンコードされた文字列は decodeURI() 関数 (livedocs@lab) を使って元に戻すことができます。

var str:String = encodeURI("http://w.c/a?b+ま&");
trace(str); // http://w.c/a?b+%E3%81%BE& が出力される
trace(decodeURI(str)); // http://w.c/a?b+ま& が出力される

encodeURIComponent() 関数と decodeURIComponent() 関数

encodeURIComponent() 関数 (livedocs@lab) は encodeURI() とほぼ同じような関数ですが、encodeURI() が URI 全体をエンコードするためのものであるのに対し、encodeURIComponent() は URI コンポーネントと呼ばれる URI の一部分をエンコードするための関数です。

URI コンポーネントとは ":", "/", ";" 等の記号で区切られた文字列です。例えば http や www.adobe.com は URI コンポーネントです。

実際に encodeURI() と encodeURIComponent() でエンコードした結果を比べると以下のようになります。どこが違うか分かりますか?

var str:String = "http://w.c/a?b+ま&";
trace(encodeURI(str)); // http://w.c/a?b+%E3%81%BE& が出力される
trace(encodeURIComponent(str)); // http%3A%2F%2Fw.c%2Fa%3Fb%2B%E3%81%BE%26 が出力される

encodeURIComponent() では ":" や "/" もエンコードの対象になっています。これは encodeURIComponent() が URI の区切りに使われる記号を特別扱いしないからです。

英字と数字以外で encodeURIComponent() がエンコードしない文字は以下のとおりです。

- _ . ! ~ ' ( )

encodeURIComponent() でエンコードされた文字列は decodeURIComponent() 関数 (livedocs@lab) で元に戻します。

var str:String = encodeURIComponent("http://w.c/a?b+ま&");
trace(str); // http%3A%2F%2Fw.c%2Fa%3Fb%2B%E3%81%BE%26 が出力される
trace(decodeURIComponent(str)); // http://w.c/a?b+ま& が出力される

Posted by ackie at 06:14 PM | Comments (0)

June 06, 2006

文字列のエスケープ

escape() 関数と unescape() 関数

escape() 関数は (livedocs@lab) は文字列を URL エンコードのフォーマットに変換するグローバル関数です。基本的に、英数字以外の文字であれば % 付の16進数に変換されます。+ などいくつか変換されない文字もあります。

trace(escape("1+3%2=0")); // 1+3%252%3D0 が出力される
trace(escape("h:m@u/a?b&c")); // h%3Am@u/a%3Fb%26c が出力される
trace(escape("ハロー")); // %u30CF%u30ED%u30FC が出力される

escape() で変換された文字を戻すには unescape() 関数 (livedocs@lab) を使います。

var str:String = escape("1+3%2=0");
trace(str); // 1+3%252%3D0 が出力される
trace(unescape(str)); // 1+3%2=0 が出力される

escapeMultiByte() 関数と unescapeMultiByte() 関数

escapeMultiByte() 関数 (livedocs@lab) と unescapeMultiByte() 関数 (livedocs@lab) は flash.utils パッケージに含まれる関数です。

escapeMultiByte() は文字列を UTF-8 もしくはシステムのコードページ (Shift-JIS 等) に変換した文字列を返します。

どちらのエンコーディングになるかは System.useCodePage の値で決まります。true の場合は OS のコードページ、false の場合は UTF-8 です。

var str:String = "もなか";
// 比較のために URL エンコーディングの結果を確認
trace(escape(str)); // %u3082%u306A%u304B が出力される
// OS のコードページ(SJIS)にエンコード
System.useCodePage = true;
trace(escapeMultiByte(str)); // %82%E0%82%C8%82%A9 が出力される
// UTF-8 にエンコード
System.useCodePage = false;
trace(escapeMultiByte(str)); // %E3%82%82%E3%81%AA%E3%81%8B が出力される

変換した文字列を戻すには unescapeMultiByte() 関数を使用します。

var str:String = escapeMultiByte("もなか");
trace(str); // %82%E0%82%C8%82%A9 が出力される
trace(unescapeMultiByte(str)); // もなか が出力される

unescapeMultiByte() も escapeMultiByte() と同様に System.useCodePage の値により結果が変わります。unescapeMultiByte() で元の文字列に戻す際は escapeMultiByte() で変換した際と System.useCodePage の値が同じである必要があります。自動的に UTF-8 かどうかを判定してくれたりはしません。

また、 System.useCodePage=true で変換した場合の結果はシステムのコードページに依存します。そのため、エンコードとデコードが同じコードページのシステム上で行われないと元の文字列に戻せません。例えば Shift-JIS で変換した文字列はShift-JIS の環境でしか戻せなくなります。

Posted by ackie at 07:17 PM | Comments (0)

June 01, 2006

NaN と Infinity

NaN と Infinity

Number 型は浮動小数点数以外に3つの値を持ちます。

最初の2つは Infinity と -Infinity です。Infinity は正の無限大の意味で Number.POSITIVE_INFINITY として定義されています。Number.MAX_VALUE の範囲を超えた値はこれになります。同様に-Infinity は負の無限大の意味で Number.NEGATIVE_INFINITY として定義されています。こっちは -Number.MAX_VALUE よりも小さい値ということになります。

3つ目の値は NaN で、Number ではない値という値です。Number.NaN でも使えます。

これら3つの値は、それぞれ以下のような場合に使われます。

trace(1 / 0); // Infinity が出力される
trace(-1 / 0); // -Infinity が出力される
trace(0 / 0); // NaN が出力される
trace(Math.sqrt(-1)); // NaN が出力される

最後の例では負の数の平方根を求めようとしているため結果が NaN になっています。(解が実数でないため)

ところで、NaN は条件文で比較すると結果が必ず false になります。

trace(1/0 == Infinity); // true が出力される
trace(0/0 == NaN); // false が出力される
trace(NaN == NaN); // false が出力される

そのために isNaN() というグローバル関数が用意されています。NaN かどうかを調べる際にはこれを使います。

trace(isNaN(0/0)); // true が出力される

同様に Infinity や -Infinity を調べるための isFinite() 関数もあります。

trace(isFinite(1/1)); // true が出力される
trace(isFinite(0/1)); // false が出力される
trace(Infinity == Infinity); // true が出力される
trace(Infinity == -Infinity); // false が出力される

Infinity と -Infinity はちゃんと区別されます。

Posted by ackie at 05:50 PM | Comments (0)