ひだかです。
kikwai@... (機械伯爵) wrote:
> RubyのMix-inは、まだちょっと理解できてないので、どなたか・・・
Ruby の Mix-in は制限された多重継承の一種です。
module M
def f
end
end
class C
include M
end
とやれば、クラスCにインスタンスメソッドfが追加されます。
Ruby の Class は単一継承ですが、複数のクラスで実装を
共有するために、Mix-in を使うことができます。
ではただの多重継承との違いはというと、ModuleとClassの
違いに還元できると思います。
Ruby の Module と Class の違いには、
・Class を include することはできない
・Module はインスタンスを生成できない
・Module は他の Module/Class を継承できない(include はできる)
と言った点があげられます。
機能的には、実際のところC++ での virtual public 継承と
ほとんど変わらないことができるとは思います。
ですが、Mix-in というのは、他のクラスに機能を追加するための
付加的なもの、という意味合いがあります。つまり、単独では
機能しなくて、includeした側のクラスのほかのメソッドと協調して
動作することがほとんどです。
# Module で完結していて、他のメソッドと無関係なものを
# 追加したい例ってあるのかな?
たとえば、Ruby組み込みのComparableモジュールでは、
クラスの <=> 演算子を定義しておけば、その他の比較演算子を
全部定義してくれます。ですが、Comparable だけが存在しても
全然使い道がありません。
このように、単独では意味をなさないですから、インスタンスを
生成できる必要はありません。C++ なら純粋仮想関数として
比較メソッドを宣言するようなクラスになることでしょう。
そのようなものを、Mix-in module として定義することで、
・Mix-inされるモジュール自身は「もの」ではない
・include する側のクラスから見ても、モジュールとの is-a 関係は弱い
・でも実装は利用したい
ということを明示できるようになるわけです。
まとめると、多重継承したい場合にはいくつかの理由があると
思うのですが、
・単に実装を共有するための都合でクラス階層が深くなる
・クラス階層を横断する形で共有するコードが書きにくい
(= さらに階層が深くなる)
といった問題を解決できるのが Mix-in ということに
なると思います。
あれ、まとまっているのかな(^_^;;;
--
ひだかたかひろ cv8t-hdk@...-net.or.jp