HTML5テクニカルノート CreateJS 14/12/12: 新たな継承の仕組みを定めるextend()とpromote()メソッド
説明CreateJSモジュールのユーティリティメソッドは、それぞれが別のJavaScriptファイルになっています。名前空間createjsに続けてメソッドを直接呼出します。 スーパークラスを継承するとき、JavaScriptコードでは多くの場合、コンストラクタのFunction.prototypeプロパティをスーパークラスのオブジェクトで書替えます(「クラスの継承と透視投影」の「Shapeクラスを継承する3次元座標のクラス定義」参照)。これまでのCreateJSでも、このかたちで継承が行われていました。
そのやり方に変わって新たに備わったのが、extend()メソッドです。サブクラスとスーパークラスのコンストラクタをふたつの引数としてメソッドに渡せば、継承がかたちづくられます。CreateJSのクラスの継承は、これから内部的にはextend()メソッドで行われることになりました。
なお、extend()メソッドは、サブクラスのコンストラクタ関数のプロトタイプオブジェクトを上書きします。したがって、コンストラクタを定めたすぐ後に呼出さなければなりません。 promote()メソッドを用いると、サブクラスからオーバーライドしたスーパークラスのメソッドが呼出せます。メソッド第2引数の接頭辞にスーパークラス名を与えれば、サブクラスに対して「スーパークラス_メソッド」で参照が得られるようになります。このとき、スーパークラスのコンストラクタは「スーパークラス_constructor」で参照されます。
function.call()やFunction.apply()メソッドでスーパークラスのメソッドをサブクラスのオブジェクトに対して呼出すより、高いパフォーマンスが得られます。なお、スーパークラスのメソッドがオーバーライドされているかどうか確かめますので、promote()メソッドはサブクラスのFunction.prototypeプロパティにメソッドをすべて定めてから呼出さなければなりません。 例以下のコード001は、extend()メソッドでサブクラス(MySubClass)にスーパークラス(MySuperClass)を継承します(第5行目)。サブクラスのオブジェクト(foo)はinstanceof演算子でスーパークラスを継承することが確かめられ、constructorプロパティによりサブクラスのコンストラクタが参照されます(第7〜8行目)。スーパークラスのコンストラクタは呼出されませんので、その本体のステートメント(第2行目)は実行されません。 コード001■extend()メソッドでクラスを継承する
extend()メソッドを使わず(第5行目)、サブクラス(MySubClass)のFunction.prototypeプロパティにスーパークラス(MySuperClass)のオブジェクトを定めても継承はできます(第5行目上のコメント行)。けれど、この場合constructorプロパティは、スーパークラスのコンストラクタを参照します(第8行目の結果はfalse)。また、スーパークラスのコンストラクタを呼出しますので、その本体の処理が実行されます(第2行目)。 以下のコード002は、2次元座標と3次元座標のふたつのクラス(Vector2DとVector3D)を定めます。前者はCreateJSのPointクラス、後者は2次元座標のクラスを、extend()メソッドで継承しました(第4および第14行目)。ふたつのクラスはともに座標をコンストラクタの引数として受取り(第1および第10行目)、原点からその座標までの距離を同じ名前のメソッド(getLength())で返します(第5〜8行目および第15〜19行目)。 そこで、どちらのクラスもpromote()メソッドにスーパークラス名を接頭辞の引数に渡して呼出しました(第9および第20行目)。すると、それぞれのコンストラクタからスーパークラスのコンストラクタは、「this.スーパークラス_constructor()」で呼出せます(第2行目および第11行目)。また、オーバーライドしたスーパークラスのメソッド(getLength())も、クラス名の接頭辞つきで参照しています(第16行目)。 コード002■3次元座標のクラスから2次元座標のオーバーライドした距離のメソッドを呼出す
なお、3次元空間の原点からxyz座標までの距離は、xy平面におけるxy座標とz座標を三平方の定理で2度組合わせて求めることができます(図001)。原点(0, 0, 0)から(1, 1, 1)までの距離は√3です(第21〜22行目)。 図001■原点からxy座標までの距離にz座標を三平方の定理で組合わせる 実装extend()メソッドの実装は、つぎのとおりです。メソッド内でクラス(o)を定め、プロトタイプオブジェクトはスーパークラスから参照を得て、Object.constructorプロパティにはサブクラスのコンストラクタを与えています(第3〜4行目)。そして、そのインスタンスをサブクラスのプロトタイプオブジェクトに定めて返します(第5行目)。
extend()とpromote()メソッドにより、CreateJS内部のクラスの基本的な実装も変わりました。 たとえば、これまでのContainerクラスは、DisplayObjectを以下のようなやり方で継承していました。まず、サブクラスのコンストラクタのFunction.prototypeプロパティをスーパークラスのオブジェクトで置替えます(第4行目)。つぎに、コンストラクタはinitialize()メソッドを呼出すだけです(第1〜3行目)。その代わり、スーパークラスのinitialize()メソッドは別の名前に置換えてから、自らのinitialize()メソッドを定めなければなりません(第5〜8行目)。
EaselJS 0.8.0では、Containerクラスの実装はつぎのようにextend()メソッドで継承されます(第4行目)。また、promote()メソッドによりスーパークラスのコンストラクタがたやすく参照できるので、initialize()メソッドはもはや定めません(第5行目および第2行目)。
作成者: 野中文雄 Copyright © 2001-2014 Fumio Nonaka. All rights reserved. |
||||||||||||||||||||||||||||||||||||