(メインページへ)
4.3 継承

4.3 継承

ビルトインクラスの拡張

Dateクラス、String、Soundクラスといったビルトインクラス(Flash標準装備のクラス)をスーパークラスにすることで、ビルトインクラスを拡張したサブクラスを作ることができます。次の例ではDateクラスを拡張して今日の曜日名を漢字で返すgetYoubi()関数と”年月日(曜日)”で日付を返すgetLongDate()関数を組み込んでいます。

sample→ex04-03/yoDateフォルダ


クラス定義ファイル:YoDate.as
//Dateクラスを拡張する
class YoDate extends Date {
var youbiList:Array = ["日", "月", "火", "水", "木", "金", "土"];
var y:Number;
var m:Number;
var d:Number;
var youbi:String;
var longdate:String;
//コンストラクタ
function YoDate() {
}
//今日の曜日を返す
function getYoubi():String {
youbi = youbiList[this.getDay()];
return (youbi);
}
//長い日付を返す
function getLongDate():String {
y = this.getFullYear();
m = this.getMonth() + 1;
d = this.getDate();
youbi = this.getYoubi();
longdate = y + "." + m + "." + d + " (" + youbi + ")";
return (longdate);
}
}

では、実際にYoDateクラスを試してみましょう。YoDateクラスはDateクラスを継承しているので、YoDateクラスでインスタンスthedayを作ると今日の日付のDateオブジェクトが作られます。続いてインスタンスthedayに対してYoDateクラスで定義した2つの関数とDateクラスのsetFullYear()関数を実行してみます。この結果からYoDateクラスはDateクラスをスーパークラスとして確かに継承していることが確認できます。

フレームアクション:yodate.fla
var theday:YoDate = new YoDate();
//YoDateクラスで定義した関数
youbi = theday.getYoubi();
trace(youbi); // 出力→ 金
longdate = theday.getLongDate();
trace(longdate); // 出力→ 2005.1.14 (金)
//Dateクラスの関数
theday.setFullYear(2005, 3, 3);
longdate = theday.getLongDate();
trace(longdate); // 出力→ 2005.4.3 (日)

個別リンク

静的(static)クラスの拡張

次に静的(static)クラスを拡張する方法を紹介します。ActionScriptユーザーガイドには「TextField クラスや、Math、Key、Mouse などの静的クラスを拡張することはできません。」と書いてありますが、やり方によってはこれらのビルトインクラスの静的クラスも拡張できます。次の例ではMathクラスをスーパークラスとしたYoMathTestクラスを作り、数値を指定の桁数に四捨五入するyoRound()関数を追加します。スクリプトで使っているMath.pow(a,b)メソッドはaのb階乗を返す関数です。

sample→ex04-03/yoMathフォルダ

クラス定義ファイル:YoMathTest.as
//Mathクラスを拡張する
class YoMathTest extends Math {
//コンストラクタ
function YoMathTest() {
}
//指定の桁数にまるめる
function yoRound(v:Number, keta:Number) {
var tmpV = v * Math.pow(10, keta);
var ans = Math.round(tmpV) / Math.pow(10, keta);
return ans;
}
}

yoRound()関数を使って12.345を小数点以下2桁に四捨五入してみると12.35になることがわかります。

フレームアクション:yomathtest.fla
myObj = new YoMathTest();
x = myObj.yoRound(12.345,2)
trace(x); // 出力→ 12.35

しかし、Mathクラスのround()関数はMath.round()の書式で利用できます。これと同じようにyoRound()関数を利用できるようにするには、次のようにstaticキーワードでyoRound()関数をクラスメンバー(静的メンバー)に指定します。クラスのインスタンスを作らずにメンバーを利用することから、コンストラクタ関数もアクセスできないようにprivateに指定します。

クラス定義ファイル:YoMath.as
//Mathクラスを拡張する
class YoMath extends Math {
//コンストラクタ--privateにする
private function YoMath() {
}
//指定の桁数にまるめる--staticにする
static function yoRound(v:Number, keta:Number) {
var tmpV = v * Math.pow(10, keta);
var ans = Math.round(tmpV) / Math.pow(10, keta);
return ans;
}
}


YoMathクラスのyoRound()関数はインスタンスを作らなくても利用できます。

フレームアクション:yomath_1.fla
y = YoMath.yoRound(12.345,2)
trace(y) // 出力→ 12.35

ただ、これではYoMathクラスが本当にMathクラスを継承しているのかどうか判断できません。そこで、次のテストを行ってみます。次のスクリプトのYoMath.PIは、スーパークラスのMath.PIを参照します。このようにYoMathはMathクラスのメンバーを利用できることがわかります。

フレームアクション:yomath_2.fla
Math; // ←スーパークラスを参照しておく
pi = YoMath.yoRound(YoMath.PI, 2);
trace(pi); // 出力→ 3.14

このフレームアクションにおいてMathクラスを一度呼び出している理由は、タイムラインでは先にスーパークラスにアクセスした後からでないとスーパークラスのクラスメンバーの参照に失敗してしまうからです。この点に注意が必要です。
これでYoMathクラスがMathクラスを継承していることを確認できましたが、ビルトインクラスの静的クラスはいつでもどこからでも利用できることから、わざわざ継承して使う意味はあまりないかもしれません。

個別リンク

オーバーライド/ポリモーフィズム

ところで、YoMath.yoRound()関数を次のようにround()という名前にしてしまうとどうなるでしょうか。round()関数はスーパークラスであるMathクラスにもある関数です。このような場合はサブクラスで定義したroud()関数が優先されます。このようにスーパークラスと同じ名前のメンバーをサブクラスで再定義することを「オーバーライド(override)」するといい、このような手法は「ポリモーフィズム(polymorphism:多態性)」と呼ばれています。


sample→ex04-03/overrideフォルダ

クラス定義ファイル:YoMath.as
class YoMath extends Math {
//コンストラクタ
private function YoMath() {
}
//指定の桁数にまるめる --- Mathクラスのround()をオーバーライドする
static function round(v:Number, keta:Number) {
var tmpV = v * Math.pow(10, keta);
var ans = Math.round(tmpV) / Math.pow(10, keta);
return ans;
}
}

Mathクラスのround()関数をオーバーライドしたYoMathクラスのround()関数をテストすると次のようになります。

フレームアクション:yomath_3.fla
a = YoMath.round(23.85, 0)
trace(a) // 出力→ 24
b = YoMath.round(23.85, 1)
trace(b) // 出力→ 23.9

note:
オーバーライドと似た用語にオーバーロード(overload)があります。オーバーロードとは引数の型に応じて同名のメソッドをコンパイル時に振り分ける機能であり、ActionScriptはオーバーロードをサポートしていません。

個別リンク

MovieClipクラスの拡張

MovieClipクラスを拡張する場合には、リンケージプロパティでムービークリップシンボルとクラス定義ファイルとの関連付けを行うことができます。関連付けを行うと、シンボルからムービークリップインスタンスを作るだけで、そのインスタンスではアクションを書き込まずとも関連付けておいたクラスのプロパティとメソッドを利用できるようになります。この場合にもパブリッシュしたswfにクラス定義ファイルを付けて配布する必要はありません。
次のRolloverクラスには、ムービークリップインスタンスにカーソルをロールオーバーするとインスタンスの縦横サイズが150%に拡大し、ロールアウトすると元の100%のサイズに戻す2つの機能があります。extends MovieClipのようにMovieClipクラスを継承している点に注目してください。

sample→ex04-03/exMC/Rollover.as

クラス定義ファイル:Rollover.as
//MovieClipクラスの継承
class Rollover extends MovieClip {
//コンストラクタ
function Rollover(){
}
//ロールオーバーしたら150%サイズ
function onRollOver() {
_xscale = 150;
_yscale = 150;
}
//ロールアウトしたら100%サイズ
function onRollOut() {
_xscale = 100;
_yscale = 100;
}
}

このRolloverクラスをムービークリップシンボルと関連付けるには、ムービークリップシンボルをライブラリウィンドウで選択して[リンケージ...]を開きます。続いて[ActionScriptに書き出し]をチェックし[識別子]と[AS2.0クラス]を指定します。[AS2.0クラス]フィールドにはクラス名のRolloverを入力します。


図4-3-2 ムービークリップシンボルのリンケージプロパティを開き、識別子とAS2.0クラスを設定します。


ムービークリップシンボルとクラスとの関連付けが終わったならば、シンボルをステージにドロップしてインスタンスを作ります。ムービーをプレビューするとロールオーバー/ロールアウトでRolloverクラスで指定しているようにサイズが変わることがわかります。


sample→ex04-03/exMC/rollovermc.fla

図4-3-3 シンボルから作ったインスタンスはロールオーバーで拡大します。

もう1つサンプルを試してみましょう。次のRotorクラスはクリックで回転と停止を切り替える機能があります。このRotorクラスもまたMovieClipクラスを継承しています。

sample→ex04-03/exMC/RotorMC.as

クラス定義ファイル:RotorMC.as
//MovieClipクラスを継承する
//MovieClipクラスを継承する
class RotorMC extends MovieClip {
var speed:Number = 10;
//コンストラクタ
function RotorMC() {
}
//クリックでスイッチング
function onPress() {
if (typeof (onEnterFrame) == "function") {
//回転を止める
delete onEnterFrame;
} else {
//回転し続ける
onEnterFrame = function () {
_rotation += speed;
};
}
}
}

続いて、Rollクラスのときと同じようにRotorクラスをムービークリップシンボルのリンケージパネルを開いて関連付けます。


図4-3-4 ムービークリップシンボルのリンケージプロパティを開き、識別子とAS2.0クラスを設定します。

ムービークリップシンボルとクラスとの関連付けが終わったならば、シンボルをステージにドロップしてインスタンスを作ります。ムービーをプレビューしてインスタンスをクリックすると回転と停止が切り替わります。

図4-3-5 クリックで回転と停止が切り替わります。

attachMovie()メソッドを使えば、ムービークリップのインスタンスをスクリプトで作ることができます。次のスクリプトは、ムービーを再生中にリンケージシンボルstarMCからインスタンスを3個作ります。リンケージシンボルstarMCにはRotorMCクラスが関連付けてあるので、クリックで回転と停止が切り替わるインスタンスになります。


フレームアクション:attachmc.fla
this.makemc();
function makemc() {
for (i = 1; i <= 3; i++) {
var depth = this.getNextHighestDepth();
var x = 50 * i;
var y = 30 * i;
var props = {_x:x, _y:y};
var mcname = "star" + depth;
//ムービークリップシンボルのインスタンスを作る
this.attachMovie("starMC", mcname, depth, props);
}
}

図4-3-6 attachMovie()メソッドを使ってリンケージシンボルからインスタンスを作成します。

note:
ムービークリップシンボルとクラスの関連付けはObject.registerClass()を使って行うこともできますが、ActionScript2.0ではリンケージプロパティで関連付けます。

*訂正 (2006.06.19 )
初版のp.141のスクリプトに間違いがありました。
誤:
class RotorMC extends MovieClip{

正:
class Rollover extends MovieClip {

個別リンク