回答:
最初の答えは適切で、いくつかの構造的な答えを提供しますが、別のアプローチはあなたが何をしているのかを考えることです。モジュールとは、複数のクラスで使用できるメソッドを提供することです。それらを「ライブラリ」と考えてください(Railsアプリで見られるように)。クラスはオブジェクトに関するものです。モジュールは関数に関するものです。
たとえば、認証および承認システムはモジュールの良い例です。認証システムは複数のアプリレベルのクラスで機能します(ユーザーは認証され、セッションは認証を管理し、他の多くのクラスは認証状態に基づいて異なる動作をします)。したがって、認証システムは共有APIとして機能します。
また、複数のアプリでメソッドを共有している場合にもモジュールを使用できます(ここでも、ライブラリモデルが適しています)。
╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║ ║ class ║ module ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated ║ can *not* be instantiated ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage ║ object creation ║ mixin facility. provide ║
║ ║ ║ a namespace. ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass ║ module ║ object ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods ║ class methods and ║ module methods and ║
║ ║ instance methods ║ instance methods ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance ║ inherits behaviour and can║ No inheritance ║
║ ║ be base for inheritance ║ ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion ║ cannot be included ║ can be included in classes and ║
║ ║ ║ modules by using the include ║
║ ║ ║ command (includes all ║
║ ║ ║ instance methods as instance ║
║ ║ ║ methods in a class/module) ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension ║ can not extend with ║ module can extend instance by ║
║ ║ extend command ║ using extend command (extends ║
║ ║ (only with inheritance) ║ given instance with singleton ║
║ ║ ║ methods from module) ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝
まだ誰も言っていないことに驚いています。
質問者はJavaのバックグラウンドから来た(そして私もそうだった)ので、これが役立つアナロジーです。
クラスは単にJavaクラスのようなものです。
モジュールはJava静的クラスのようなものです。Math
Javaのクラスについて考えてみましょう。あなたはそれをインスタンス化せず、静的クラス(例えばMath.random()
)のメソッドを再利用します。
extend self
)、そのメソッドをself
のメタクラスで使用できるようにします。これはrandom()
、Math
モジュールのようなメソッドをディスパッチすることを可能にします。ただし、その性質上、モジュールのメソッドをモジュール自体で呼び出すことはできませんself
。これは、Rubyのの概念self
、メタクラス、およびメソッドルックアップの動作に関係しています。詳細については、「メタプログラミングRuby」のPaolo Perlottaを参照してください。
基本的に、モジュールはインスタンス化できません。クラスにモジュールが含まれる場合、すべてのモジュールメソッドとクラスメソッドへのアクセスを提供するプロキシスーパークラスが生成されます。
モジュールは複数のクラスに含めることができます。モジュールを継承することはできませんが、この「mixin」モデルは便利なタイプの「多重継承」を提供します。オブジェクト指向の純粋主義者はその声明に反対しますが、仕事を成し遂げる上で純粋さが邪魔されないようにしてください。
(この回答はもともとにリンクされてhttp://www.rubycentral.com/pickaxe/classes.html
いましたが、そのリンクとそのドメインはアクティブではなくなりました。)
extend
。Rubyは実際には「インスタンス」メソッドと「クラス/静的」メソッドをまったく区別せず、それらのレシーバーのみを区別します。
Module
Rubyでは、ある程度、Java 抽象クラスに対応します。インスタンスメソッドがあり、クラスはそれから継承できます(include
Rubyの連中はこれを「ミックスイン」と呼びます)が、インスタンスはありません。他にも小さな違いはありますが、これだけの情報があれば始められます。
名前空間:モジュールは名前空間であり、Javaには存在しません;)
私もJavaとpythonからRubyに切り替えましたが、まったく同じ質問があったことを覚えています...
したがって、最も単純な答えは、モジュールがJavaには存在しない名前空間であるということです。Javaでは、名前空間に最も近い考え方はパッケージです。
それで、rubyのモジュールはjava:
クラスのようなものですか?
インターフェースなし?
抽象クラスはありませんか?
パッケージなし?多分そうだね)
Javaのクラス内の静的メソッド:Rubyのモジュール内のメソッドと同じ
Javaでは、最小単位はクラスであり、クラスの外部に関数を持つことはできません。ただし、Rubyではこれが可能です(Pythonなど)。
それでは、モジュールには何が入りますか?
クラス、メソッド、定数。モジュールはその名前空間の下でそれらを保護します。
インスタンスなし:モジュールを使用してインスタンスを作成することはできません
混合イン:継承モデルはクラスに適していない場合がありますが、機能の観点から、一連のクラス/メソッド/定数をグループ化したい
ルビのモジュールに関する規則:
-モジュール名はUpperCamelCaseです
-モジュール内の定数はすべて大文字です(この規則はすべてのルビ定数で同じで、モジュールに固有ではありません)
-アクセス方法:を使用します。オペレーター
-定数にアクセス:::記号を使用
モジュールの簡単な例:
module MySampleModule
CONST1 = "some constant"
def self.method_one(arg1)
arg1 + 2
end
end
モジュール内でメソッドを使用する方法:
puts MySampleModule.method_one(1) # prints: 3
モジュールの定数の使用方法:
puts MySampleModule::CONST1 # prints: some constant
モジュールに関する他のいくつかの規則:
ファイルで1つのモジュールを使用します(rubyクラス、rubyファイルごとに1つのクラスなど)。
クラス
クラスを定義するとき、データ型のブループリントを定義します。クラスはデータを保持し、そのデータと対話するメソッドを持ち、オブジェクトをインスタンス化するために使用されます。
モジュール
モジュールは、メソッド、クラス、および定数をグループ化する方法です。
モジュールには2つの大きな利点があります。
=>モジュールは名前空間を提供し、名前の衝突を防ぎます。名前空間は、他の誰かが作成した同じ名前の関数やクラスとの競合を回避するのに役立ちます。
=>モジュールはミックスイン機能を実装します。
(KlazzのModuleを含むと、KlazzのインスタンスがModuleメソッドにアクセスできます。)
(KlazzをModで拡張し、クラスKlazzがModsメソッドにアクセスできるようにします。)
まず、まだ言及されていないいくつかの類似点。Rubyはオープンクラスをサポートしていますが、モジュールもオープンクラスです。結局のところ、クラスはクラス継承チェーンのモジュールから継承するので、クラスとモジュールは同じような動作をします。
しかし、プログラミング言語でクラスとモジュールの両方を使用する目的は何であるかを自問する必要がありますか?クラスは、インスタンスを作成するための青写真であることが意図されており、各インスタンスは、青写真の実現されたバリエーションです。インスタンスは、青写真(クラス)の単なる変形です。当然、クラスはオブジェクトの作成として機能します。さらに、ある設計図が別の設計図から派生することもあるので、クラスは継承をサポートするように設計されています。
モジュールはインスタンス化できず、オブジェクトを作成せず、継承をサポートしません。したがって、1つのモジュールが別のモジュールを継承しないことを忘れないでください!
それでは、モジュールを言語で持つことの意味は何ですか?モジュールの明らかな使用法の1つは名前空間を作成することであり、他の言語でもこれに気付くでしょう。繰り返しますが、Rubyの優れている点は、モジュールを(クラスと同じように)再オープンできることです。そして、これは、異なるRubyファイルで名前空間を再利用したい場合の大きな使用法です。
module Apple
def a
puts 'a'
end
end
module Apple
def b
puts 'b'
end
end
class Fruit
include Apple
end
> f = Fruit.new
=> #<Fruit:0x007fe90c527c98>
> f.a
=> a
> f.b
=> b
ただし、モジュール間の継承はありません。
module Apple
module Green
def green
puts 'green'
end
end
end
class Fruit
include Apple
end
> f = Fruit.new
=> #<Fruit:0x007fe90c462420>
> f.green
NoMethodError: undefined method `green' for #<Fruit:0x007fe90c462420>
AppleモジュールはGreenモジュールからメソッドを継承せず、AppleをFruitクラスに含めた場合、AppleモジュールのメソッドはAppleインスタンスの祖先チェーンに追加されますが、Greenモジュールのメソッドは追加されません。モジュールはAppleモジュールで定義されました。
では、どうすれば環境に優しい方法にアクセスできますか?クラスに明示的に含める必要があります。
class Fruit
include Apple::Green
end
=> Fruit
> f.green
=> green
しかし、Rubyにはモジュールの別の重要な使用法があります。これはMixin機能であり、SOに関する別の回答で説明しています。しかし、要約すると、ミックスインを使用すると、オブジェクトの継承チェーンにメソッドを定義できます。ミックスインを使用して、オブジェクトインスタンスの継承チェーン(インクルード)またはセルフのシングルトンクラス(拡張)にメソッドを追加できます。