クラスとモジュールの違い


回答:


398

最初の答えは適切で、いくつかの構造的な答えを提供しますが、別のアプローチはあなたが何をしているのかを考えることです。モジュールとは、複数のクラスで使用できるメソッドを提供することです。それらを「ライブラリ」と考えてください(Railsアプリで見られるように)。クラスはオブジェクトに関するものです。モジュールは関数に関するものです。

たとえば、認証および承認システムはモジュールの良い例です。認証システムは複数のアプリレベルのクラスで機能します(ユーザーは認証され、セッションは認証を管理し、他の多くのクラスは認証状態に基づいて異なる動作をします)。したがって、認証システムは共有APIとして機能します。

また、複数のアプリでメソッドを共有している場合にもモジュールを使用できます(ここでも、ライブラリモデルが適しています)。


7
モジュールはJavaのインターフェイスと同じですか?
Saad Rehman Shah

14
@Caffeineは、Rubyモジュールが実際に実装を含んでいるのとは異なり、Javaのインターフェースは抽象的です
Jorge

8
いいえ、モジュールとJavaパッケージ/ JARはまったく異なります。
Karoly Horvath 2013年

9
私はメソッドを実装した抽象クラスに似ています。
Automatico

2
実際、@ Choleは、モジュールの優れた点の1つであるNamespacingにぶつかります。したがって、モジュールはJavaのパッケージと直接同等ではありませんが、これを使用して同様のことを実現できます。blog.rubybestpractices.com
gregory

513
╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ 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)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝

「クラス」クラスのスーパークラスは何ですか?
Aashish P 2012

10
私は階層、クラス->モジュール->オブジェクト-> BasicObjectを得ました。涼しい!!
Aashish P 2012

クラスとモジュールの両方がクラス変数をサポートしているのに、なぜ「モジュールで構成される」変数が省略されるのですか?stackoverflow.com/questions/5690458/…
kaleidic

これらのすべての答えにはたくさんの図があります。少し実行例:rubyfiddle.com/riddles/06081
Donato

16
モジュールはどのようにして「インスタンス化されない」で、まだインスタンスメソッドを持つことができますか?
devius

91

まだ誰も言っていないことに驚いています。

質問者はJavaのバックグラウンドから来た(そして私もそうだった)ので、これが役立つアナロジーです。

クラスは単にJavaクラスのようなものです。

モジュールはJava静的クラスのようなものです。MathJavaのクラスについて考えてみましょう。あなたはそれをインスタンス化せず、静的クラス(例えばMath.random())のメソッドを再利用します。


11
ただし、モジュールはインクルードクラスにインスタンスメソッドを追加できますが、Javaの静的クラスはできません。
モニカの復活-notmaynard 2013年

4
このステートメントは、C#のバックグラウンドが重い場合にも当てはまります。
デイモンドレイク

5
これは完全に正しいわけではありません。モジュールには静的メソッドはなく、メソッドだけがあります。モジュールは「自分自身を拡張する」ことができ(構文は実際にはextend self)、そのメソッドをselfのメタクラスで使用できるようにします。これはrandom()Mathモジュールのようなメソッドをディスパッチすることを可能にします。ただし、その性質上、モジュールのメソッドをモジュール自体で呼び出すことはできませんself。これは、Rubyのの概念self、メタクラス、およびメソッドルックアップの動作に関係しています。詳細については、「メタプログラミングRuby」のPaolo Perlottaを参照してください。
scottburton11 2015

モジュールはメソッドを含むインターフェース(デフォルトの
実装で

この回答はどのようにして多くの票を獲得しましたか?ところで、1か月前に、より良い言葉で言われました:stackoverflow.com/a/17027346/986862
Andre Figueiredo

39

基本的に、モジュールはインスタンス化できません。クラスにモジュールが含まれる場合、すべてのモジュールメソッドとクラスメソッドへのアクセスを提供するプロキシスーパークラスが生成されます。

モジュールは複数のクラスに含めることができます。モジュールを継承することはできませんが、この「mixin」モデルは便利なタイプの「多重継承」を提供します。オブジェクト指向の純粋主義者はその声明に反対しますが、仕事を成し遂げる上で純粋さが邪魔されないようにしてください。


(この回答はもともとにリンクされてhttp://www.rubycentral.com/pickaxe/classes.htmlいましたが、そのリンクとそのドメインはアクティブではなくなりました。)


うん、これはそれがどのように機能するかです。そのため、モジュールはJavaの「静的」クラスに相当しません。プロキシスーパークラス(いくつかのコールそれを「メタクラスは」)になり、モジュールのメソッドのディスパッチメッセージの受信機となり、それは、Javaの静的クラスに匹敵し、そしてその方法は、静的メソッドのように動作します。ただし、Rubyのクラスについても同じことが言えます。Rubyのクラスでは、クラスを使用することで「静的」なメソッドを実行できますextend。Rubyは実際には「インスタンス」メソッドと「クラス/静的」メソッドをまったく区別せず、それらのレシーバーのみを区別します。
scottburton11

7

ModuleRubyでは、ある程度、Java 抽象クラスに対応します。インスタンスメソッドがあり、クラスはそれから継承できます(includeRubyの連中はこれを「ミックスイン」と呼びます)が、インスタンスはありません。他にも小さな違いはありますが、これだけの情報があれば始められます。


6

名前空間:モジュールは名前空間であり、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つのクラスなど)。


「-アクセス方法:を使用します。演算子-定数へのアクセス:「::記号を使用する」
Qiulang 2018

4

結論:モジュールは、静的/ユーティリティクラスとミックスインのクロスです。

ミックスインは再利用可能な「部分的」実装の一部であり、新しいクラスの作成に役立つように、ミックス&マッチ方式で組み合わせる(または構成する)ことができます。もちろん、これらのクラスはさらに独自の状態やコードを持つことができます。


1

クラス

クラスを定義するとき、データ型のブループリントを定義します。クラスはデータを保持し、そのデータと対話するメソッドを持ち、オブジェクトをインスタンス化するために使用されます。

モジュール

  • モジュールは、メソッド、クラス、および定数をグループ化する方法です。

  • モジュールには2つの大きな利点があります。

    =>モジュールは名前空間を提供し、名前の衝突を防ぎます。名前空間は、他の誰かが作成した同じ名前の関数やクラスとの競合を回避するのに役立ちます。

    =>モジュールはミックスイン機能を実装します。

(KlazzのModuleを含むと、KlazzのインスタンスがModuleメソッドにアクセスできます。)

(KlazzをModで拡張し、クラスKlazzがModsメソッドにアクセスできるようにします。)


0

まず、まだ言及されていないいくつかの類似点。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に関する別の回答で説明しています。しかし、要約すると、ミックスインを使用すると、オブジェクトの継承チェーンにメソッドを定義できます。ミックスインを使用して、オブジェクトインスタンスの継承チェーン(インクルード)またはセルフのシングルトンクラス(拡張)にメソッドを追加できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.