Posted at

継承やインクルードをうまいことしてみる

More than 3 years have passed since last update.

各クラス共通で使用する可能性のあるメソッド群を、適宜継承(extends)させて使用してて、正しい継承の必要が出てきたときに共通モジュール的なクラスはどうすればいいのかいろいろ考えて一応自分の中で結論づけた

やりたいこと

class Oya

constructor: (@name) ->
oyaMethod: ->

class Ko extends Oya
include Utility
constructor: (name) -> super name
koMethod: ->

ko = new Ko 'name'
ko.utilityMethod()

要は、 Ruby の Module インクルード的なことをやりたい

ここ とかに Mixin の例があってあーいいかもとか思ったけど、でも結局 Module クラスを extends してる

結局、 Module というクラスを用意してクラスメソッドとして、 include を定義してクラス内で使用するという結論となりました

class Module

@include: (obj, mixin) ->
for own key, value of mixin
obj::[key] = value
return this

class Ko extends Oya
Module.include @, Utility
constructor: (name) -> super name
koMethod: ->

CoffeeScript の継承をみてみると実体は以下

__extends = function(child, parent) {

for (var key in parent) {
if (__hasProp.call(parent, key)) {
child[key] = parent[key];
}
}

function ctor() {
this.constructor = child;
}

ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.__super__ = parent.prototype;

return child;
};

なのでついでに extend メソッドも追加してみる

class Module

@extend = (child, parent) ->
for own key of parent
child[key] = parent[key]

ctor = ->
@constructor = child
return

ctor:: = parent::
child:: = new ctor
child.__super__ = parent::

return child

@include: (obj, mixin) ->
for own key, value of mixin
obj::[key] = value
return this

class Ko
Module.extend @, Oya
Module.include @, Utility
constructor: (name) -> super name
koMethod: ->

具体的には、こんなカスタムイベントを管理するクラスを定義して、適宜インクルードして使いたかった

class Events

@on: (event, cb) ->

@off: (event, cb) ->

@trigger: (names...) ->

ほかにいい方法あったら教えてください