2008-09-30 3 views
351

Ich kam aus Java, und jetzt arbeite ich mehr mit Ruby.Unterschied zwischen einer Klasse und einem Modul

Eine Sprachfunktion, die ich nicht kenne, ist die module. Ich frage mich, was genau ist eine module und wann verwenden Sie eine, und warum verwenden Sie eine module über eine class?

+22

http : //goo.gl/p95BL6 Dieses Diagramm kann helfen. – shin

Antwort

336

Die erste Antwort ist gut und gibt einige strukturelle Antworten, aber ein anderer Ansatz ist, zu denken über was du tust. In Modulen geht es darum, Methoden zur Verfügung zu stellen, die Sie für mehrere Klassen verwenden können - denken Sie an sie als "Bibliotheken" (wie Sie es in einer Rails-App sehen würden). Klassen sind über Objekte; Module sind über Funktionen.

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

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

+6

Ist das Modul dasselbe wie Interfaces in Java? –

+10

@Caffeine nicht wirklich, weil Ruby-Module tatsächlich Implementierungen enthalten, während Interfaces in Java abstrakt sind –

+0

Ahh! Aha! Module sind Pakete oder JARs und Klassen sind Klassen! – Chloe

37

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

Ein Modul kann von mehreren Klassen enthalten sein. Module können nicht vererbt werden, aber dieses "Mixin" -Modell bietet eine nützliche Art von "Mehrfacherben". OO-Puristen werden dieser Aussage nicht zustimmen, aber lassen Sie sich nicht durch Reinheit davon abhalten, den Job zu erledigen.


(Diese Antwort ursprünglich http://www.rubycentral.com/pickaxe/classes.html verbunden, aber das Link und seiner Domäne sind nicht mehr aktiv.)

+0

Ja, so funktioniert es. Damit sind Module * nicht * vergleichbar mit Javas "statischen" Klassen; Die Proxy-Oberklasse (manche nennen sie eine "Metaklasse") wird zum Empfänger der Methoden-Dispatch-Nachrichten des Moduls, was * it * mehr mit einer statischen Klasse in Java vergleichbar macht und deren Methoden wie statische Methoden funktionieren. Dasselbe gilt jedoch für Rubys Klassen, die "statische" Methoden annehmen können, indem sie eine Klasse erweitern. Ruby unterscheidet nicht wirklich zwischen "instance" und "class/static" Methoden, nur die Empfänger von ihnen. – scottburton11

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

Was ist die Oberklasse der Klassenklasse? –

+5

Ich habe die Hierarchie, Klasse -> Modul -> Objekt -> BasicObject. Cool!! –

+0

Warum besteht "Modul besteht aus" Variablen auslassen, wenn Klassen und Module beide Klassenvariablen unterstützen? Siehe akzeptierte Antwort zu http://stackoverflow.com/questions/5690458/create-module-variables-in-ruby – kaleidic

7

Module in Ruby, zu einem gewissen Grad entspricht Java abstrakte Klasse - Instanz-Methoden hat, können Klassen von ihm erben (via include Ruby Jungs nennen es eine "mixin"), hat aber keine Instanzen. Es gibt noch andere geringfügige Unterschiede, aber diese vielen Informationen reichen aus, um Ihnen den Einstieg zu erleichtern.

71

Ich bin überrascht, dass jemand das noch nicht gesagt hat.

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

Klassen sind einfach wie Java-Klassen.

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

+9

Aber Module können der Include-Klasse auch Instanzmethoden hinzufügen, während statische Klassen in Java dies nicht können. – iamnotmaynard

+3

Diese Aussage trifft auch auf einen schweren C# -Hintergrund zu. –

+2

Dies ist nicht ganz richtig; Module haben keine statischen Methoden, sie haben nur Methoden. Module können sich "erweitern" (die Syntax ist eigentlich "selbst erweitern"), wodurch ihre Methoden für ihre Metaklasse "selbst" verfügbar werden. Dies ermöglicht es, eine Methode wie 'random()' auf einem 'Math'-Modul zu versenden. Aufgrund ihrer Natur können die Methoden eines Moduls nicht auf dem eigenen Selbst des Moduls aufgerufen werden. Dies hat mit Rubys Begriff von "self", seinen Metaklassen und der Funktionsweise von Methoden-Lookup zu tun. Schauen Sie sich "Metaprogramming Ruby" - Paolo Perlotta für Details an. – scottburton11

2

source

Ein Modul ist eine Sammlung von Methoden und Konstanten (Sie können die Eigenschaften des Moduls von dort lernen). Die Methoden in einem Modul können Instanzmethoden oder Modulmethoden sein. Instanzmethoden erscheinen als Methoden in einer Klasse, wenn das Modul enthalten ist, Modulmethoden nicht. Umgekehrt können Modulmethoden aufgerufen werden, ohne ein Kapselungsobjekt zu erstellen, während Instanzmethoden dies nicht tun können.

3

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

Mixins sind wiederverwendbare Teile von "partiellen" Implementierungen, die in einer Mischung & Match-Mode kombiniert werden können (oder komponieren), um neue Klassen zu schreiben. Diese Klassen können natürlich ihren eigenen Status und/oder Code haben.

1

Klasse

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

Modul

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

  • Module geben Ihnen zwei große Vorteile:

    => Module einen Namespace zur Verfügung stellen und Namenskonflikte vermeiden. Namespace hilft Konflikte mit Funktionen und Klassen mit demselben Namen zu vermeiden, die von jemand anderem geschrieben wurden.

    => Module implementieren die Mixin-Einrichtung.

(inklusive des Moduls in Klazz gibt Instanzen von Klazz Zugang Methoden Modul.)

(verlängern Klazz mit Mod die Klasse Klazz Zugriff auf Mods Methoden zu geben.)