Différence entre une classe et un module

Je viens de Java et maintenant je travaille davantage avec Ruby.

Une fonctionnalité linguistique que je ne connais pas bien est le module . Je me demande quel est exactement un module et quand en utilisez-vous un, et pourquoi utiliser un module sur une class ?

La première réponse est bonne et donne des réponses structurelles, mais une autre approche consiste à réfléchir à ce que vous faites. Les modules ont pour but de fournir des méthodes que vous pouvez utiliser dans plusieurs classes – pensez à les considérer comme des “bibliothèques” (comme vous le verrez dans une application Rails). Les classes concernent des objects; les modules concernent les fonctions.

Par exemple, les systèmes d’authentification et d’autorisation sont de bons exemples de modules. Les systèmes d’authentification fonctionnent sur plusieurs classes au niveau de l’application (les utilisateurs sont authentifiés, les sessions gèrent l’authentification, de nombreuses autres classes agissent différemment en fonction de l’état d’authentification), les systèmes d’authentification agissant comme des API partagées.

Vous pouvez également utiliser un module lorsque vous avez partagé des méthodes entre plusieurs applications (encore une fois, le modèle de bibliothèque est bon ici).

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

Je suis surpris que quelqu’un n’ait pas encore dit ça.

Étant donné que le demandeur venait d’un environnement Java (et moi aussi), voici une analogie qui aide.

Les classes sont simplement comme les classes Java.

Les modules sont comme les classes statiques Java. Pensez à la classe de Math en Java. Vous ne l’instanciez pas et vous réutilisez les méthodes de la classe statique (par exemple, Math.random() ).

Fondamentalement, le module ne peut pas être instancié. Lorsqu’une classe comprend un module, une super-classe proxy est générée pour donner access à toutes les méthodes de module ainsi qu’aux méthodes de classe.

Un module peut être inclus par plusieurs classes. Les modules ne peuvent pas être hérités, mais ce modèle “mixin” fournit un type utile “d’inheritance multiple”. Les puristes d’OO ne seront pas d’accord avec cette affirmation, mais ne laissez pas la pureté entraver le travail.


(Cette réponse était à l’origine liée à http://www.rubycentral.com/pickaxe/classes.html , mais ce lien et son domaine ne sont plus actifs.)

Module dans Ruby, dans une certaine mesure, correspond à la classe abstraite Java – a des méthodes d’instance, des classes peuvent en hériter (via include , les gars de Ruby l’appellent un “mixin”), mais n’a pas d’instance. Il y a d’autres différences mineures, mais ces informations suffisent pour vous permettre de démarrer.

Bottom line: Un module est un croisement entre une classe statique / utilitaire et un mixin.

Les mixins sont des implémentations “partielles” réutilisables, qui peuvent être combinées (ou composées) de manière à créer de nouvelles classes. Ces classes peuvent en outre avoir leur propre état et / ou code, bien sûr.

source (Vous pouvez apprendre les caractéristiques du module à partir de là)

Un module est un ensemble de méthodes et de constantes. Les méthodes d’un module peuvent être des méthodes d’instance ou des méthodes de module. Les méthodes d’instance apparaissent comme des méthodes dans une classe lorsque le module est inclus, contrairement aux méthodes de module. Inversement, les méthodes de module peuvent être appelées sans créer d’object d’encapsulation, contrairement aux méthodes d’instance.

Classe

Lorsque vous définissez une classe, vous définissez un modèle pour un type de données. classe hold data, ont une méthode qui interagit avec ces données et sont utilisées pour instancier des objects.

Module

  • Les modules permettent de regrouper des méthodes, des classes et des constantes.

  • Les modules vous apportent deux avantages majeurs:

    => Les modules fournissent un espace de noms et empêchent les conflits de noms. L’espace de noms permet d’éviter les conflits avec les fonctions et les classes portant le même nom qui ont été écrites par quelqu’un d’autre.

    => Les modules implémentent la fonction mixin.

(y compris Module dans Klazz donne des exemples d’access de Klazz aux méthodes du module.)

(étendre Klazz avec Mod donnant access à la classe Klazz aux méthodes Mods.)

namespace: les modules sont des espaces de noms … qui n’existent pas dans java;)

Je suis aussi passé de Java et de python à Ruby, je me souviens de la même question …

La réponse la plus simple est que ce module est un espace de noms, qui n’existe pas en Java. Dans java, l’état d’esprit le plus proche de l’espace de noms est un package .

Donc, un module en ruby ​​est comme en java:
classe? Non
interface? Non
classe abstraite? Non
paquet? Oui peut-être)

méthodes statiques à l’intérieur de classes dans java: idem méthodes à l’intérieur de modules dans ruby

En java, l’unité minimale est une classe, vous ne pouvez pas avoir de fonction en dehors d’une classe. Cependant en ruby ​​c’est possible (comme python).

Alors, qu’est-ce qui entre dans un module?
classes, méthodes, constantes. Le module les protège sous cet espace de noms.

Aucune instance: les modules ne peuvent pas être utilisés pour créer des instances

Mixed ins: parfois, les modèles d’inheritance ne conviennent pas aux classes, mais en termes de fonctionnalité, vous souhaitez regrouper un ensemble de classes / méthodes / constantes

Règles sur les modules dans ruby:
– Les noms de module sont UpperCamelCase
– les constantes dans les modules sont ALL CAPS (cette règle est la même pour toutes les constantes Ruby, non spécifiques aux modules)
– méthodes d’access: utiliser. opérateur
– constantes d’access: use :: symbol

exemple simple d’un module:

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

comment utiliser les méthodes à l’intérieur d’un module:

 puts MySampleModule.method_one(1) # prints: 3 

comment utiliser les constantes d’un module:

 puts MySampleModule::CONST1 # prints: some constant 

Quelques autres conventions sur les modules:
Utiliser un module dans un fichier (comme les classes ruby, une classe par fichier ruby)

Tout d’abord, certaines similitudes qui n’ont pas encore été mentionnées. Ruby prend en charge les classes ouvertes, mais les modules sont également ouverts. Après tout, Class hérite de Module dans la chaîne d’inheritance de classes et Class et Module ont donc un comportement similaire.

Mais vous devez vous demander quel est le but d’avoir à la fois une classe et un module dans un langage de programmation? Une classe est destinée à être un modèle pour la création d’instances, et chaque instance est une variation réalisée du modèle. Une instance n’est qu’une variation réalisée d’un plan (la classe). Naturellement, les classes fonctionnent comme des objects. De plus, étant donné que nous souhaitons parfois qu’un schéma provienne d’un autre modèle, les classes sont conçues pour prendre en charge l’inheritance.

Les modules ne peuvent pas être instanciés, ne créent pas d’objects et ne prennent pas en charge l’inheritance. Alors rappelez-vous qu’un module n’hérite pas d’un autre!

Alors, quel est l’intérêt d’avoir des modules dans un langage? Une utilisation évidente de Modules est de créer un espace de noms, et vous le remarquerez également avec d’autres langages. Encore une fois, ce qui est cool avec Ruby, c’est que les modules peuvent être rouverts (tout comme les classes). Et c’est une grande utilisation lorsque vous voulez réutiliser un espace de noms dans différents fichiers 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 => # > fa => a > fb => b 

Mais il n’y a pas d’inheritance entre les modules:

 module Apple module Green def green puts 'green' end end end class Fruit include Apple end > f = Fruit.new => # > f.green NoMethodError: undefined method `green' for # 

Le module Apple n’a pas hérité de méthodes du module Green et lorsque nous avons inclus Apple dans la classe Fruit, les méthodes du module Apple sont ajoutées à la chaîne ancêtre des instances Apple, mais pas les méthodes du module Green, même si le module Green le module a été défini dans le module Apple.

Alors, comment pouvons-nous avoir access à la méthode verte? Vous devez l’inclure explicitement dans votre classe:

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

Mais Ruby a une autre utilisation importante pour les modules. C’est l’installation Mixin que je décris dans une autre réponse sur SO. Mais pour résumer, les mixins vous permettent de définir des méthodes dans la chaîne d’inheritance des objects. Grâce aux mixins, vous pouvez append des méthodes à la chaîne d’inheritance des instances d’object (include) ou à la classe singleton_class de self (extend).