2008-09-30 35 views
351

Vengo de Java, y ahora estoy trabajando más con Ruby.Diferencia entre una clase y un módulo

Una característica del idioma con la que no estoy familiarizado es el module. Me pregunto qué es exactamente un module y cuándo se usa uno, y por qué usar un module sobre un class?

+22

http : //goo.gl/p95BL6 Este diagrama puede ayudar. – shin

Respuesta

336

La primera respuesta es buena y da algunas respuestas estructurales, pero otro enfoque es pensar sobre lo que estás haciendo Los módulos tratan de proporcionar métodos que puede usar en múltiples clases: piense en ellos como "bibliotecas" (como vería en una aplicación de Rails). Las clases son sobre objetos; los módulos son sobre funciones.

Por ejemplo, los sistemas de autenticación y autorización son buenos ejemplos de módulos. Los sistemas de autenticación funcionan en múltiples clases de nivel de aplicación (los usuarios son autenticados, las sesiones administran la autenticación, muchas otras clases actuarán de forma diferente en función del estado de autenticación), de modo que los sistemas de autenticación actúan como API compartidas.

También puede utilizar un módulo cuando tenga métodos compartidos en varias aplicaciones (una vez más, el modelo de la biblioteca es bueno aquí).

+6

¿Es el módulo lo mismo que las interfaces en java? –

+10

@Cafeína no realmente porque los módulos de Ruby en realidad incluyen implementaciones, mientras que las interfaces en Java son abstractas –

+0

¡Ahh! ¡Ya veo! ¡Los módulos son paquetes o JAR y las clases son clases! – Chloe

37

Básicamente, no se puede crear una instancia del módulo. Cuando una clase incluye un módulo, se genera una superclase de proxy que proporciona acceso a todos los métodos de módulo así como a los métodos de clase.

Un módulo puede ser incluido por múltiples clases. Los módulos no se pueden heredar, pero este modelo "mixin" proporciona un tipo útil de "herencia múltiple". Los puristas de OO estarán en desacuerdo con esa afirmación, pero no permita que la pureza se interponga en el camino de hacer el trabajo.


(Esta respuesta originalmente vinculado a http://www.rubycentral.com/pickaxe/classes.html, pero ese enlace y su dominio han sido desactivados.)

+0

Sí, así es como funciona. Como tal, los módulos son * no * comparables a las clases "estáticas" de Java; la superclase proxy (algunos lo llaman una "metaclase") se convierte en el receptor de los mensajes de despacho de métodos del módulo, lo que hace * it * más comparable a una clase estática en Java, y sus métodos funcionan como métodos estáticos. Lo mismo es cierto, sin embargo, para las clases de Ruby, que pueden adoptar métodos "estáticos" al "extender" una clase. Ruby en realidad no distingue entre los métodos de "instancia" y "clase/estática", solo los receptores de ellos. – 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

¿Cuál es la clase superior de la clase 'Clase'? –

+5

Obtuve la jerarquía, Clase -> Módulo -> Objeto -> ObjetoBásico. ¡¡Guay!! –

+0

¿Por qué el "módulo consiste en" omitir variables, cuando las clases y los módulos admiten variables de clase? Ver respuesta aceptada a http://stackoverflow.com/questions/5690458/create-module-variables-in-ruby – kaleidic

7

Module en Ruby, hasta cierto punto, corresponde a Java clase abstracta - tiene los métodos de instancia, las clases pueden heredar de ella (a través de include, Ruby chicos llaman un "mixin"), pero no tiene instancias. Hay otras diferencias menores, pero esta mucha información es suficiente para comenzar.

71

Me sorprende que nadie haya dicho esto todavía.

Como el asker viene de un fondo Java (y yo también), aquí hay una analogía que ayuda.

Las clases son simplemente como las clases de Java.

Los módulos son como las clases estáticas de Java. Piense en la clase Math en Java. No lo instancia, y reutiliza los métodos en la clase estática (por ejemplo, Math.random()).

+9

Pero los módulos también pueden agregar métodos de instancia a la clase incluida, mientras que las clases estáticas en Java no pueden. – iamnotmaynard

+3

Esta afirmación también es cierta proveniente de un fondo pesado de C#. –

+2

Esto no es del todo cierto; los módulos no tienen métodos estáticos, solo tienen métodos. Los módulos pueden "extenderse" (la sintaxis es en realidad "extenderse uno mismo"), haciendo que sus métodos estén disponibles para la metaclass de su "self". Esto hace posible enviar un método como 'random()' en un módulo 'Math'. Pero, por su naturaleza, los métodos de un módulo no se pueden invocar en el propio "self" del módulo. Esto tiene que ver con la noción de Ruby de "self", sus metaclases y cómo funciona la búsqueda de métodos. Consulte "Metaprogramación Ruby" - Paolo Perlotta para más detalles. – scottburton11

2

source (usted puede aprender las características del módulo de allí)

Un módulo es un conjunto de métodos y constantes. Los métodos en un módulo pueden ser métodos de instancia o métodos de módulo. Los métodos de instancia aparecen como métodos en una clase cuando se incluye el módulo, los métodos de módulo no. Por el contrario, se pueden llamar a los métodos de módulo sin crear un objeto de encapsulado, mientras que los métodos de instancia pueden no serlo.

3

Línea inferior: Un módulo es un cruce entre una clase estática/de utilidad y una mixin.

Mixins son piezas reutilizables de implementación "parcial", que se pueden combinar (o componer) en una combinación de formas &, para ayudar a escribir nuevas clases. Estas clases también pueden tener su propio estado y/o código, por supuesto.

1

Clase

Cuando se define una clase, se define un modelo para un tipo de datos. datos de clase retenidos, tienen un método que interactúa con esos datos y se utilizan para crear instancias de objetos.

Módulo

  • módulos son una forma de agrupar juntos métodos, clases, y constantes.

  • módulos que dan dos beneficios principales:

    => módulos proporcionan un espacio de nombres y evitan conflictos de nombre. El espacio de nombres ayuda a evitar conflictos con funciones y clases con el mismo nombre escrito por otra persona.

    => Los módulos implementan la función mixin.

(incluyendo módulo en Klazz da ejemplos de acceso Klazz al Módulo métodos.)

(extender Klazz con Mod dando el acceso Klazz clase a métodos Mods.)

Cuestiones relacionadas