メソッド

メソッドは、クラス定義に含まれる関数です。クラスのインスタンスが作成されると、メソッドはそのインスタンスにバインドされます。メソッドは、クラス外で宣言された関数とは異なり、その関連付けられているインスタンスと別個に使用することはできません。

メソッドは、function キーワードを使用して定義します。次のような関数ステートメントを使用できます。

public function sampleFunction():String {}

または、関数式を割り当てる変数を次のように使用することもできます。

public var sampleFunction:Function = function () {}

多くの場合、関数式ではなく関数ステートメントを使用するのは、次のような理由のためです。

関数式を使用する必要があるのは、関数をプロトタイプオブジェクトに関連付ける場合などです。詳細については、プロトタイプオブジェクトを参照してください。

サブトピック

コンストラクタメソッド
静的メソッド
インスタンスメソッド
get および set アクセサメソッド
バインドメソッド

コンストラクタメソッド

コンストラクタメソッドは、単にコンストラクタと呼ばれることもあり、定義されたクラスと同じ名前を共有する関数です。コンストラクタメソッドに含まれるコードは、クラスのインスタンスが new キーワードで作成されるときに実行されます。たとえば、次のコードは、status という名前のプロパティを 1 つ含む単純なクラス Example を定義します。status 変数の初期値は、コンストラクタ関数内で設定します。

class Example
{
    public var status:String;
    public function Example()
    {
        status = "initialized";
    }
}

var myExample:Example = new Example();
trace(myExample.status); // 出力 : initialized

コンストラクタメソッドにはパブリックだけを指定できますが、public 属性を使用するかどうかは任意です。コンストラクタに、privateprotectedinternal やその他のアクセス制御指定子を使用することはできません。また、ユーザー定義の名前空間をコンストラクタメソッドで使用することもできません。

コンストラクタは、super() ステートメントを使用して直接のスーパークラスのコンストラクタを明示的に呼び出すことができます。スーパークラスのコンストラクタを明示的に呼び出さない場合は、コンパイラによってコンストラクタ本体の最初のステートメントの前に呼び出しが自動的に挿入されます。スーパークラスへの参照として super 接頭辞を使用し、スーパークラスのメソッドを呼び出すこともできます。同じコンストラクタ本体で super()super を使用する場合は、必ず最初に super() を呼び出します。呼び出さないと、super 参照は意図したとおりに動作しません。super() コンストラクタも、throw または return ステートメントの前に呼び出す必要があります。

次に、super() コンストラクタを呼び出す前に super 参照を使用しようとした場合の例を示します。新しいクラス ExampleEx は Example クラスを拡張します。ExampleEx コンストラクタは、super() を呼び出す前に、スーパークラスで定義された status 変数にアクセスしようとします。ExampleEx コンストラクタ内の trace() ステートメントは、値 null を生成します。これは、super() コンストラクタが実行されるまで status 変数を使用できないからです。

class ExampleEx extends Example
{
    public function ExampleEx()
    {
        trace(super.status);
        super();
    }
}

var mySample:ExampleEx = new ExampleEx(); // 出力 : null

コンストラクタ内で return ステートメントを使用することはできますが、値を返すことはできません。つまり、return ステートメントに式または値を関連付けることはできません。したがって、コンストラクタメソッドは値を返すことができず、戻り値の型を指定できません。

クラスでコンストラクタメソッドを定義しなかった場合、コンパイラが自動的に空のコンストラクタを作成します。クラスが別のクラスを拡張する場合、コンパイラには、そのコンパイラが生成するコンストラクタ内の super() 呼び出しが含まれます。

静的メソッド

静的メソッドは、クラスメソッドとも呼ばれ、static キーワードで宣言されたメソッドです。静的メソッドは、クラスのインスタンスではなくクラスに関連付けられ、個々のインスタンスの状態以外のものに影響を与える機能のカプセル化に役立ちます。静的メソッドはクラス全体に関連付けられるため、クラスのインスタンスではなくクラスからのみアクセスできます。

静的メソッドは、クラスインスタンスの状態に影響を与えるだけではない機能のカプセル化に役立ちます。つまり、メソッドにクラスインスタンスの値に直接影響しない機能がある場合、そのメソッドは静的です。たとえば、Date クラスには、ストリングを取得して数値に変換する parse() という静的メソッドがあります。このメソッドは、クラスの個々のインスタンスに影響を与えないため静的です。parse() メソッドは、日付値を表すストリングを取得し、そのストリングを解析して、Date オブジェクトの内部表現と互換性がある形式で数値を返します。このメソッドは、Date クラスのインスタンスに適用しても意味がないため、インスタンスメソッドではありません。

静的な parse() メソッドと、getMonth() などの Date クラスのインスタンスメソッドを比較してみます。getMonth() メソッドは、Date インスタンスの特定のコンポーネントである月を取得することで、インスタンスの値に対して直接実行されるため、インスタンスメソッドです。

静的メソッドは個々のインスタンスにバインドされていないので、静的メソッドの本体内で this または super キーワードを使用できません。this 参照および super 参照は、インスタンスメソッドのコンテキスト内でのみ有効です。

他のクラスベースのプログラミング言語とは異なり、ActionScript 3.0 では静的メソッドは継承されません。詳細については、継承されない静的プロパティを参照してください。

インスタンスメソッド

インスタンスメソッドは、static キーワードを使用せずに宣言されたメソッドです。インスタンスメソッドは、クラス全体ではなくクラスのインスタンスに関連付けられ、クラスの個々のインスタンスに影響を与える機能の実装に役立ちます。たとえば、Array クラスには、Array インスタンスに直接実行される sort() という名前のインスタンスメソッドが含まれています。

インスタンスメソッドの本体内では、静的変数およびインスタンス変数はスコープ内にあります。つまり、同じクラス内で定義された変数は、単純な識別子を使用して参照できます。たとえば、次の CustomArray クラスは Array クラスを拡張します。CustomArray クラスは、クラスインスタンスの総数を追跡する静的変数 arrayCountTotal、インスタンスが作成された順序を追跡するインスタンス変数 arrayNumber、およびこれらの変数の値を返すインスタンスメソッド getPosition() を定義します。

public class CustomArray extends Array
{
    public static var arrayCountTotal:int = 0;
    public var arrayNumber:int;

    public function CustomArray()
    {
        arrayNumber = ++arrayCountTotal;
    }
    
    public function getArrayPosition():String
    {
         return ("Array " + arrayNumber + " of " + arrayCountTotal);
    }
}

クラス外部にあるコードは、CustomArray.arrayCountTotal を使用して、クラスオブジェクトから arrayCountTotal 静的変数を参照する必要がありますが、getPosition() メソッドの本体内にあるコードは、arrayCountTotal 静的変数を直接参照できます。これは、スーパークラスの静的変数でも同じです。ActionScript 3.0 では静的プロパティは継承されませんが、スーパークラスの静的プロパティはスコープ内です。たとえば、Array クラスにはいくつかの静的変数があり、そのうちの 1 つは DESCENDING という定数です。Array サブクラス内にあるコードは、単純な識別子を使用して静的定数 DESCENDING を参照できます。

public class CustomArray extends Array
{
    public function testStatic():void
    {
        trace(DESCENDING); // 出力 : 2
    }
}

インスタンスメソッドの本体内の this 参照の値は、メソッドが関連付けられているインスタンスへの参照です。次のコードは、this 参照がメソッドを含むインスタンスを参照していることを示します。

class ThisTest
{
    function thisValue():ThisTest
    {
        return this;
    }
}

var myTest:ThisTest = new ThisTest();
trace(myTest.thisValue() == myTest); // 出力 : true

インスタンスメソッドの継承は、overridefinal のキーワードを使用して制御できます。override 属性を使用して継承されたメソッドを定義できます。また、final 属性を使用すると、サブクラスによってメソッドがオーバーライドされないようにできます。詳細については、メソッドのオーバーライドを参照してください。

get および set アクセサメソッド

getter および setter とも呼ばれる get および set アクセサ関数を使用すると、作成したクラスの使いやすいプログラミングインターフェイスを提供すると同時に、情報を非表示およびカプセル化するというプログラミング原則に従うことができます。get および set 関数を使用して、クラスプロパティをクラスに対してプライベートに保持できますが、クラスのユーザーは、クラスメソッドを呼び出すのではなくクラス変数にアクセスしている場合と同じように、これらのプロパティにアクセスできます。

この方法の利点は、getPropertyName()setPropertyName() など、従来の冗長な名前のアクセサ関数を使用する必要がないことです。また、getter および setter には、読み取りおよび書き込みアクセスを可能にする各プロパティに対して 2 つの公開関数を持つ必要がないという利点もあります。

次の例の GetSet クラスには、privateProperty という名前のプライベート変数へのアクセスを提供する publicAccess() という名前の get および set アクセサ関数が含まれています。

class GetSet
{
    private var privateProperty:String;
    
    public function get publicAccess():String
    {
        return privateProperty;
    }
    
    public function set publicAccess(setValue:String):void
    {
        privateProperty = setValue;
    }
}

privateProperty プロパティに直接アクセスしようとすると、エラーが発生します。

var myGetSet:GetSet = new GetSet();
trace(myGetSet.privateProperty); // エラーが発生する

GetSet クラスを使用している場合は、publicAccess という名前のプロパティのように見える、privateProperty という名前のプライベートプロパティに対して動作する get と set のアクセサ関数の組み合わせを使用します。次の例では、GetSet クラスをインスタンス化し、publicAccess という名前のパブリックアクセサを使用して privateProperty の値を設定します。

var myGetSet:GetSet = new GetSet();
trace(myGetSet.publicAccess); // 出力 : null
myGetSet.publicAccess = "hello";
trace(myGetSet.publicAccess); // 出力 : hello

getter および setter 関数でも、スーパークラスから継承されるプロパティをオーバーライドできますが、通常のクラスメンバー変数を使用したときにはオーバーライドできません。var キーワードで宣言されたクラスメンバー変数は、サブクラスではオーバーライドできません。一方、getter および setter 関数を使用して作成されたプロパティにはこの制限はありません。スーパークラスから継承した getter 関数と setter 関数に override 属性を使用できます。

バインドメソッド

バインドメソッドは、メソッドクロージャとも呼ばれ、単にインスタンスから抽出されるメソッドです。バインドメソッドの例には、関数にパラメータとして渡され、関数から値として返されるメソッドがあります。ActionScript 3.0 で新しく導入されたバインドメソッドは、インスタンスから抽出されたときでもレキシカル環境が保持されるメソッドクロージャに似ています。バインドメソッドとメソッドクロージャの主な違いは、バインドメソッドの this 参照は、バインドメソッドを実装するインスタンスにリンクされたまま、つまりバインドされたままであるという点です。これは、バインドメソッドの this 参照が、常にこのメソッドを実装する元のオブジェクトを指していることを意味します。関数クロージャの場合、this 参照は汎用です。すなわち、この関数が呼び出された時点で関連付けられているオブジェクトが何であっても、そのオブジェクトを参照します。

this キーワードを使用する場合は、バインドメソッドを理解していることが重要です。this キーワードを使用すれば、メソッドの親オブジェクトを参照できます。ほとんどの ActionScript プログラマは、this キーワードが常にメソッドの定義を含むオブジェクトまたはクラスを参照すると考えますが、メソッドのバインディングがないと必ずしもそうなりません。旧バージョンの ActionScript では、たとえば、this 参照はメソッドを実装するインスタンスを常に参照するわけではありませんでした。ActionScript 2.0 でインスタンスからメソッドを抽出すると、this 参照が元のインスタンスにバインドされないだけでなく、インスタンスのクラスのメンバー変数およびメソッドも使用できません。ActionScript 3.0 では、メソッドをパラメータとして渡すとバインドメソッドが自動的に作成されるため、これは問題にはなりません。バインドメソッドにより、this キーワードは常に、メソッドが定義されたオブジェクトまたはクラスを参照します。

次のコードは、ThisTest というクラスを定義します。このクラスには、バインドメソッドを定義するメソッド foo()、およびバインドメソッドを返すメソッド bar() が含まれます。クラス外部にあるコードは、ThisTest クラスのインスタンスを作成し、bar() メソッドを呼び出して、myFunc という変数に戻り値を格納します。

class ThisTest
{
    private var num:Number = 3;
    function foo():void // 定義されたバインドメソッド
    {
        trace("foo's this: " + this);
        trace("num: " + num);
    }
    function bar():Function
    {
        return foo; // 返されたバインドメソッド
    }
}

var myTest:ThisTest = new ThisTest();
var myFunc:Function = myTest.bar();
trace(this); // 出力 : [object global]
myFunc();    
/* 出力 :
foo の this: [object ThisTest]
出力 : num: 3 */

コードの最後の 2 行は、バインドメソッド foo()this 参照が、その直前の行の this 参照がグローバルオブジェクトを指していても、依然として ThisTest クラスのインスタンスを指すことを示しています。さらに、myFunc 変数に格納されているバインドメソッドは、引き続き ThisTest クラスのメンバー変数にアクセスすることができます。この同じコードを ActionScript 2.0 で実行すると、this 参照が一致し、num 変数は undefined になります。

addEventListener() メソッドでは関数またはメソッドをパラメータとして渡す必要があるため、バインドメソッドの追加が最もわかりやすいのはイベントハンドラを使用する場合です。詳細については、クラスメソッドとして定義されたリスナー関数を参照してください。


 

このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート

現在のページ: http://livedocs.adobe.com/flash/9.0_jp/main/00000064.html