objetos modulos manejo lista instanciar herencia clases ruby class module

ruby - modulos - Diferencia entre una clase y un módulo.



modulo ruby (10)

Vengo de Java, y ahora estoy trabajando más con Ruby.

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


Básicamente, el módulo no puede ser instanciado. Cuando una clase incluye un módulo, se genera una superclase de proxy que proporciona acceso a todos los métodos del 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 no estarán de acuerdo con esa afirmación, pero no dejen que la pureza se interponga en el camino para hacer el trabajo.

(Esta respuesta estaba originalmente vinculada a http://www.rubycentral.com/pickaxe/classes.html , pero ese enlace y su dominio ya no están activos).


En pocas palabras: un módulo es un cruce entre una clase estática / utilidad y una mezcla.

Los mixins son piezas reutilizables de implementación "parcial", que se pueden combinar (o componer) de una manera mixta y combinada, para ayudar a escribir nuevas clases. Estas clases también pueden tener su propio estado y / o código, por supuesto.


En primer lugar, algunas similitudes que aún no se han mencionado. Ruby soporta clases abiertas, pero también módulos abiertos. Después de todo, Class hereda de Module en la cadena de herencia de Class, por lo que Class y Module tienen un comportamiento similar.

Pero debe preguntarse cuál es el propósito de tener una Clase y un Módulo en un lenguaje de programación. Se pretende que una clase sea un plano para crear instancias, y cada instancia es una variación realizada del plano. Una instancia es solo una variación realizada de un plano (la Clase). Naturalmente, entonces, las clases funcionan como creación de objetos. Además, dado que a veces queremos que un modelo se derive de otro modelo, las clases están diseñadas para admitir la herencia.

Los módulos no se pueden crear instancias, no crean objetos y no admiten la herencia. ¡Así que recuerda que un módulo NO se hereda de otro!

Entonces, ¿cuál es el punto de tener módulos en un idioma? Un uso obvio de los Módulos es crear un espacio de nombres, y notará esto también en otros idiomas. Una vez más, lo bueno de Ruby es que los módulos se pueden volver a abrir (al igual que las clases). Y este es un gran uso cuando se desea reutilizar un espacio de nombres en diferentes archivos de 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

Pero no hay herencia entre los módulos:

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>

El módulo de Apple no heredó ningún método del módulo verde y, cuando incluimos a Apple en la clase Fruit, los métodos del módulo de Apple se agregan a la cadena de antepasados ​​de las instancias de Apple, pero no los métodos del módulo verde, aunque el verde El módulo fue definido en el módulo de Apple.

Entonces, ¿cómo obtenemos acceso al método verde? Tienes que incluirlo explícitamente en tu clase:

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

Pero Ruby tiene otro uso importante para los módulos. Esta es la instalación de Mixin, que describo en otra respuesta en SO. Pero para resumir, los mixins le permiten definir métodos en la cadena de herencia de objetos. A través de mixins, puede agregar métodos a la cadena de herencia de instancias de objetos (incluir) o singleton_class of self (extend).


La primera respuesta es buena y da algunas respuestas estructurales, pero otro enfoque es pensar en lo que estás haciendo. Los módulos se tratan de proporcionar métodos que puede utilizar en varias clases; piénselos 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 varias clases de nivel de aplicación (los usuarios se autentican, las sesiones administran la autenticación, muchas otras clases actuarán de manera diferente según el estado de autenticación), por lo que los sistemas de autenticación actúan como API compartidas.

También puede usar un módulo cuando ha compartido métodos entre varias aplicaciones (nuevamente, el modelo de biblioteca es bueno aquí).


Me sorprende que alguien no haya dicho esto todavía.

Como el autor de la pregunta provino de un fondo de 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. Piensa en la clase de Math en Java. No lo ejemplifica, y reutiliza los métodos en la clase estática (por ejemplo, Math.random() ).


espacio de nombres: los módulos son espacios de nombres ... que no existen en java;)

También cambié de Java y python a Ruby, recuerdo que tenía exactamente esta misma pregunta ...

Así que la respuesta más simple es que el módulo es un espacio de nombres, que no existe en Java. En Java, la mentalidad más cercana al espacio de nombres es un paquete .

Así que un módulo en ruby ​​es como lo que en java:
¿clase? No
¿interfaz? No
¿clase abstracta? No
¿paquete? Si quizas)

métodos estáticos dentro de las clases en java: igual que los métodos dentro de los módulos en ruby

En java, la unidad mínima es una clase, no puede tener una función fuera de una clase. Sin embargo en Ruby esto es posible (como Python).

Entonces, ¿qué entra en un módulo?
Clases, métodos, constantes. El módulo los protege bajo ese espacio de nombres.

Ninguna instancia: los módulos no pueden usarse para crear instancias

Entradas mixtas: a veces los modelos de herencia no son buenos para las clases, pero en términos de funcionalidad, queremos agrupar un conjunto de clases / métodos / constantes

Reglas sobre los módulos en ruby:
- Los nombres de los módulos son UpperCamelCase
- las constantes dentro de los módulos son TODAS LAS CAPS (esta regla es la misma para todas las constantes ruby, no específica de los módulos)
- Métodos de acceso: uso. operador
- constantes de acceso: uso :: símbolo

Ejemplo simple de un módulo:

module MySampleModule CONST1 = "some constant" def self.method_one(arg1) arg1 + 2 end end

Cómo usar métodos dentro de un módulo:

puts MySampleModule.method_one(1) # prints: 3

Cómo usar las constantes de un módulo:

puts MySampleModule::CONST1 # prints: some constant

Algunas otras convenciones sobre módulos:
Use un módulo en un archivo (como clases de ruby, una clase por archivo de ruby)


source (Puedes aprender las características del módulo desde allí)

Un módulo es una colección 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. A la inversa, los métodos de módulo pueden llamarse sin crear un objeto de encapsulación, mientras que los métodos de instancia pueden no ser llamados.


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


Clase

Cuando define una clase, define un plano para un tipo de datos. los datos de retención de clase, tienen un método que interactúa con esos datos y se utilizan para instanciar objetos.

Módulo

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

  • Los módulos le dan dos grandes beneficios:

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

    => Módulos implementan la facilidad de mezcla.

(Incluyendo el Módulo en Klazz le da a Klazz acceso a los métodos del Módulo).

(amplíe Klazz con Mod para que la clase Klazz acceda a los métodos Mods).


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