it-swarm.com.de

Unterschied zwischen einer Klasse und einem Modul

Ich komme aus Java und arbeite jetzt mehr mit Ruby.

Eine mir unbekannte Sprachfunktion ist die module. Ich frage mich, was genau ein module ist und wann Sie einen verwenden und warum ein module über einem class verwendet wird.

423
Josh Moore

Die erste Antwort ist gut und gibt einige strukturelle Antworten, aber ein anderer Ansatz besteht darin, darüber nachzudenken, was Sie tun. Bei Modulen geht es darum, Methoden bereitzustellen, die Sie für mehrere Klassen verwenden können - stellen Sie sich diese als "Bibliotheken" vor (wie Sie es in einer Rails App) sehen würden. Bei Klassen geht es um Objekte, bei Modulen um Funktionen.

Beispielsweise sind Authentifizierungs- und Autorisierungssysteme gute Beispiele für Module. Authentifizierungssysteme funktionieren über mehrere Klassen auf App-Ebene (Benutzer sind authentifiziert, Sitzungen verwalten die Authentifizierung, viele andere Klassen verhalten sich je nach Authentifizierungsstatus anders), sodass Authentifizierungssysteme als gemeinsam genutzte APIs fungieren.

Sie können ein Modul auch verwenden, wenn Sie Methoden für mehrere Apps gemeinsam nutzen (auch hier ist das Bibliotheksmodell gut).

388
scottru
╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ 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)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝
504
Sergii Shevchyk

Ich bin überrascht, dass das noch niemand gesagt hat.

Da der Fragesteller aus einem Java Hintergrund kam (und ich auch), ist hier eine Analogie, die hilft.

Klassen sind einfach wie Java Klassen.

Module sind wie Java statische Klassen. Denken Sie an die Klasse Math in Java. Sie instanziieren sie nicht und verwenden die Methoden in der statischen Klasse (z. B. Math.random()).

86
Linan

Grundsätzlich kann das Modul nicht instanziiert werden. Wenn eine Klasse ein Modul enthält, wird eine Proxy-Superklasse generiert, die den Zugriff auf alle Modulmethoden sowie die Klassenmethoden ermöglicht.

Ein Modul kann von mehreren Klassen aufgenommen werden. Module können nicht vererbt werden, aber dieses "Mixin" -Modell bietet eine nützliche Art der "Mehrfachvererbung". OO Puristen werden mit dieser Aussage nicht einverstanden sein, aber lassen Sie nicht zu, dass Reinheit die Erledigung der Aufgabe behindert.


(Diese Antwort war ursprünglich verknüpft mit http://www.rubycentral.com/pickaxe/classes.html, aber dieser Link und seine Domain sind nicht mehr aktiv.)

39
hurcane

Module in Ruby entspricht zu einem gewissen Grad Java abstrakte Klasse - hat Instanzmethoden, Klassen können davon erben (über include, Ruby Jungs nennen es ein "Mixin"), hat aber keine Instanzen. Es gibt andere kleine Unterschiede, aber diese vielen Informationen reichen aus, um Ihnen den Einstieg zu erleichtern.

7
Boris Stitnicky

namespace: Module sind Namespaces ... die in Java;) nicht existieren

Ich habe auch von Java und python zu Ruby gewechselt, ich erinnere mich, dass ich genau die gleiche Frage hatte ...

Die einfachste Antwort ist also, dass das Modul ein Namespace ist, der in Java nicht existiert. In Java ist die dem Namespace am nächsten kommende Einstellung package.

Ein Modul in Ruby ist wie in Java:
Klasse? Nein
Schnittstelle? Nr
abstrakte Klasse? Nein
Paket? Ja (vielleicht)

statische Methoden in Klassen in Java: Entspricht den Methoden in Modulen in Ruby

In Java ist die minimale Einheit eine Klasse, Sie können keine Funktion außerhalb einer Klasse haben. In Ruby ist dies jedoch möglich (wie Python).

Was steckt also in einem Modul?
Klassen, Methoden, Konstanten. Das Modul schützt sie unter diesem Namespace.

Keine Instanz: Module können nicht zum Erstellen von Instanzen verwendet werden

Mixed ins: Vererbungsmodelle eignen sich manchmal nicht für Klassen, möchten aber in Bezug auf die Funktionalität eine Reihe von Klassen/Methoden/Konstanten zusammenfassen

Regeln zu Modulen in Ruby:
- Die Modulnamen lauten UpperCamelCase
- Konstanten in Modulen sind ALL CAPS (diese Regel gilt für alle Ruby Konstanten, nicht modulspezifisch)
- Zugriffsmethoden: verwenden. Operator
- Zugriffskonstanten: use :: symbol

einfaches Beispiel eines Moduls:

module MySampleModule
  CONST1 = "some constant"

  def self.method_one(arg1)
    arg1 + 2
  end
end

so verwenden Sie Methoden in einem Modul:

puts MySampleModule.method_one(1) # prints: 3

so verwenden Sie Konstanten eines Moduls:

puts MySampleModule::CONST1 # prints: some constant

Einige andere Konventionen zu Modulen:
Verwenden Sie ein Modul in einer Datei (wie Ruby Klassen, eine Klasse pro Ruby Datei)

5
apadana

Fazit: Ein Modul ist eine Kreuzung zwischen einer static/utility-Klasse und einem Mixin.

Mixins sind wiederverwendbare Teile einer "partiellen" Implementierung, die in einer Mix & Match-Weise kombiniert (oder zusammengestellt) werden können, um beim Schreiben neuer Klassen zu helfen. Diese Klassen können natürlich zusätzlich einen eigenen Status und/oder Code haben.

4
IQ Sayed

Klasse

Wenn Sie eine Klasse definieren, definieren Sie einen Entwurf für einen Datentyp. Klassenhaltedaten, Methoden, die mit diesen Daten interagieren und zum Instanziieren von Objekten verwendet werden.

Modul

  • Module sind eine Möglichkeit, Methoden, Klassen und Konstanten zu gruppieren.

  • Module bieten Ihnen zwei wesentliche Vorteile:

    => Module stellen einen Namensraum zur Verfügung und verhindern Namenskonflikte. Mithilfe von Namespaces können Konflikte mit Funktionen und Klassen mit demselben Namen vermieden werden, die von einer anderen Person geschrieben wurden.

    => Module implementieren die Mixin-Funktion.

(Wenn Sie Module in Klazz einbinden, erhalten Sie Instanzen von Klazz-Zugriff auf Module-Methoden.)

(Erweitern Sie Klazz mit Mod, um der Klasse Klazz Zugriff auf Mods-Methoden zu gewähren.)

1
prasanthrubyist

Erstens einige Ähnlichkeiten, die noch nicht erwähnt wurden. Ruby unterstützt offene Klassen, aber auch offene Module. Schließlich erbt Class von Module in der Class-Vererbungskette, sodass Class und Module ein ähnliches Verhalten aufweisen.

Aber Sie müssen sich fragen, welchen Zweck es hat, sowohl eine Klasse als auch ein Modul in einer Programmiersprache zu haben. Eine Klasse soll eine Blaupause zum Erstellen von Instanzen sein, und jede Instanz ist eine realisierte Variation der Blaupause. Eine Instanz ist nur eine realisierte Variante eines Bauplans (der Klasse). Natürlich fungieren Klassen dann als Objekterstellung. Da wir manchmal möchten, dass eine Blaupause von einer anderen Blaupause abgeleitet wird, unterstützen Klassen die Vererbung.

Module können nicht instanziiert werden, erstellen keine Objekte und unterstützen keine Vererbung. Denken Sie also daran, dass ein Modul NICHT von einem anderen erbt!

Was macht es dann für einen Sinn, Module in einer Sprache zu haben? Eine offensichtliche Verwendung von Modulen besteht darin, einen Namespace zu erstellen, und Sie werden dies auch bei anderen Sprachen bemerken. Das Coole an Ruby ist, dass Module wieder geöffnet werden können (genau wie Klassen). Und dies ist eine große Verwendung, wenn Sie einen Namespace in verschiedenen Ruby -Dateien wiederverwenden möchten:

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

Es gibt jedoch keine Vererbung zwischen Modulen:

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>

Das Apple -Modul hat keine Methoden vom Green-Modul geerbt, und wenn wir Apple in die Fruit-Klasse aufgenommen haben, werden die Methoden des Apple -Moduls zum hinzugefügt Vorfahrenkette von Apple Instanzen, jedoch keine Methoden des Green-Moduls, obwohl das Green-Modul im Apple Modul definiert wurde.

Wie erhalten wir Zugang zur grünen Methode? Sie müssen es explizit in Ihre Klasse aufnehmen:

class Fruit
  include Apple::Green
end
 => Fruit 
 > f.green
=> green

Aber Ruby hat eine andere wichtige Verwendung für Module. Dies ist die Mixin-Einrichtung, die ich in einer anderen Antwort auf SO beschreibe. Zusammenfassend können Sie mit Mixins Methoden in der Vererbungskette von Objekten definieren. Durch Mixins können Sie der Vererbungskette von Objektinstanzen (include) oder der singleton_class von self (extend) Methoden hinzufügen.

0
Donato