Ruby : モジュールとクラス
http://www.rubyist.net/~matz/20060624.html#p02を見て、はたと考える。
「全部モジュールにしてもいいのでは」という指摘には、どういう意味があるのだろうか?
-
-
- -
-
まず、確認しておくことは、Rubyは動的型チェックなので、サブタイプ関係を作ることに意味がないということ。これは、Javaで言うところの次の関係のことを指している。
class A {} class B extends A {} A a = new B();
ここで、BはAのサブタイプなので、A型の変数にB型のオブジェクトを代入することが許可される。しかし、Rubyでは動的型付けなのでそもそもサブタイプ関係がなくても代入することは問題ない。
-
-
- -
-
ところで、モジュールは継承することができないという特徴がある(らしい)。この特徴があるおかげで、菱形継承を避けながら多重継承を行うことを実現している。
また、クラスは継承を行うことができるが、多重継承することはできない。メソッドの実装は、モジュールにもクラスにも行うことができる。
このことは、次のような問題がおこる可能性がある。
class A def f () end end class B def g () end end class C < A def h () end end
ここで、クラスCでクラスBのメソッドg()を使いたいと思っても、継承する術はない。(まあ、それはあたりまえだ)
しかし、次のようにモジュールを中心に組んでいれば、そういう問題は起こらない。
module A def f () end end module B def g () end end module C def h () end end class C1 include C include A include B end
モジュールCの中で、メソッドf()やメソッドg()を呼び出すとエラーになりそうな気がするが、メソッド呼び出しも動的なので問題はない。確かに、includeが3つ並ぶのはあまりかっこよくはないけれど、意味的にはこれで十分だ。
さらに、これは結局、
module C include A include B def h() end end
と書いてしまうのとあまり変わりはない。(強いて言えば、モジュールA,Bが常にincludeされるように限定されてしまうくらいのことだ)
という風に考えていくと、結局のところ、モジュールとクラスを別のものとしている意味はどこにあるのだろうか、という疑問が起こるのは理解できる気がする。
-
-
- -
-
実際、モジュールで、メソッド名の衝突が回避できるかというと、そんなことはないわけだし。