Actionscript2.0でMix-inする

Actionscript2.0はクラスベースっぽい書き方をするけど、やっぱり中身はprototypeベースなのでそれを使ってMix-inすることもできます。

試しにMix-in(も)できるDrawingUtilsクラスを作ってみました。
MovieClipを継承して、drawLineとdrawRectメソッドを追加しています。

class DrawingUtils extends MovieClip {
    static var _drawingUtils:DrawingUtils;
    static function initialize(object:Object) {
        if (_drawingUtils == undefined) {
            _drawingUtils = new DrawingUtils();
        }
        object.drawLine = _drawingUtils.drawLine;
        object.drawRect = _drawingUtils.drawRect;
    }
    
    function drawLine(x1:Number, y1:Number,
                      x2:Number, y2:Number, style:Object) {
        if (style.lineWidth != undefined
            && style.lineColor != undefined) {
            var alpha = (style.lineAlpha==undefined)
                        ? 100 : style.lineAlpha;
            lineStyle(style.lineWidth, style.lineColor, alpha);
        }
        moveTo(x1, y1);
        lineTo(x2, y2);
    }
    function drawRect(x:Number, y:Number,
                      w:Number, h:Number, style:Object) {
        var fill:Boolean = (style.fillColor != undefined);
        if (fill) {
            var alpha = (style.fillAlpha==undefined)
                        ? 100 : style.fillAlpha;
            beginFill(style.fillColor, alpha);
        }
        if (style.lineWidth != undefined
            && style.lineColor != undefined) {
            var alpha = (style.lineAlpha==undefined)
                        ? 100 : style.lineAlpha;
            lineStyle(style.lineWidth, style.lineColor, alpha);
        }
        moveTo(x, y);
        lineTo(x+w, y);
        lineTo(x+w, y+h);
        lineTo(x, y+h);
        lineTo(x, y);
        if (fill) {
            endFill();
        }
    }
}

クラスメソッドのinitializeが肝です。

drawLineやdrawRectを使いたいときは、MovieClipの代わりにこのクラスを継承して新しいクラスを作っても良いのですが、以下のようにしてdrawLineとdrawRectをMix-inすることもできます。

class MyMC extends MovieClip {
	var drawLine:Function;
	var drawRect:Function;
	
	function MyMC() {
		DrawingUtils.initialize(MyMC.prototype); // ※
		var x = Math.random()*300;
		var y = Math.random()*300;
		drawRect(x, y, 10, 10, {
			lineWidth: 1,
			lineColor: 0x0000FF,
			fillColor: 0xDDDDDD
		});
		drawLine(x, y, x+10, y+10, {
			lineWidth: 1,
			lineColor: 0x0000FF
		});
		drawLine(x+10, y, x, y+10, {
			lineWidth: 1,
			lineColor: 0x0000FF
		});
	}
}

※の箇所で、DrawingUtilsのinitializeにMyMCのprototypeを渡してあげることで、MyMCクラスにdrawLineとdrawRectが追加されます。
ただし、それだけだとdrawLineやdrawRectが定義されていないと怒られるので、

var drawLine:Function;
var drawRect:Function;

このように使いたいメソッドを宣言しておきます。そうすることでdrawLineとdrawRectをMyMCの中で使えるようになります。

MovieClipの子クラスぐらいならこのテクニックは大して必要ないですが、孫やひ孫クラスを作ったり、UIObjectを継承するようになったとき、Mix-inがあると便利です。

  • -

参考にしたページ