Разница между классом и модулем - PullRequest
419 голосов
/ 30 сентября 2008

Я пришел с Java, и теперь я больше работаю с Ruby.

Одна языковая функция, с которой я не знаком, это module. Мне интересно, что такое module и когда вы его используете, и почему используйте module вместо class?

Ответы [ 9 ]

499 голосов
/ 20 марта 2012
╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ 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)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝
384 голосов
/ 30 сентября 2008

Первый ответ хорош и дает некоторые структурные ответы, но другой подход - подумать о том, что вы делаете. Модули предназначены для предоставления методов, которые вы можете использовать в нескольких классах - думайте о них как о «библиотеках» (как вы видели бы в приложении Rails). Классы об объектах; модули о функциях.

Например, системы аутентификации и авторизации являются хорошими примерами модулей. Системы аутентификации работают в нескольких классах уровня приложения (пользователи проходят аутентификацию, сеансы управляют аутентификацией, многие другие классы будут работать по-разному в зависимости от состояния аутентификации), поэтому системы аутентификации действуют как общие API.

Вы также можете использовать модуль, когда у вас есть общие методы для нескольких приложений (опять же, модель библиотеки здесь хорошая).

85 голосов
/ 08 августа 2013

Я удивлен, что никто еще не сказал этого.

Поскольку спрашивающий пришел из Java-фона (и я тоже), вот аналогия, которая помогает.

Классы просто как классы Java.

Модули похожи на статические классы Java. Подумайте о Math классе в Java. Вы не создаете его экземпляр и повторно используете методы в статическом классе (например, Math.random()).

39 голосов
/ 30 сентября 2008

В принципе, модуль не может быть создан. Когда класс включает в себя модуль, создается прокси-суперкласс, который обеспечивает доступ ко всем методам модуля, а также к методам класса.

Модуль может быть включен несколькими классами. Модули не могут быть унаследованы, но эта модель "mixin" предоставляет полезный тип "множественного наследования". ОО-пуристы не согласятся с этим утверждением, но не позволят чистоте помешать выполнению работы.


(Этот ответ изначально был связан с http://www.rubycentral.com/pickaxe/classes.html, но эта ссылка и ее домен больше не активны.)

7 голосов
/ 10 июня 2013

Module в Ruby, в некоторой степени, соответствует Java абстрактный класс - имеет методы экземпляра, классы могут наследовать от него (через include, ребята из Ruby называют его «mixin») , но не имеет экземпляров. Есть и другие незначительные различия, но этого достаточно, чтобы начать работу.

5 голосов
/ 16 июня 2018

пространство имен: модули - это пространства имен ... которые не существуют в Java;)

Я также переключился с Java и python на Ruby, я помню, у меня был точно такой же вопрос ...

Итак, самый простой ответ заключается в том, что модуль является пространством имен, которого нет в Java. В java наиболее близким мышлением к пространству имен является пакет .

Итак, модуль в ruby ​​похож на модуль java:
класс? Нет
интерфейс? Нет
абстрактный класс? Нет
пакет? Да (может быть)

статические методы внутри классов в java: так же, как методы внутри модулей в ruby ​​

В Java минимальной единицей является класс, у вас не может быть функции вне класса. Однако в ruby ​​это возможно (как в python).

Так что входит в модуль?
классы, методы, константы. Модуль защищает их в этом пространстве имен.

Нет экземпляра: модули не могут быть использованы для создания экземпляров

Смешанные модули: иногда модели наследования не подходят для классов, но с точки зрения функциональности хотят сгруппировать набор классов / методов / констант вместе

Правила о модулях в ruby:
- Имена модулей - UpperCamelCase
- константы в модулях являются ВСЕМИ ЗАГЛУШКАМИ (это правило одинаково для всех констант ruby, не специфично для модулей)
- методы доступа: использовать. оператор
- константы доступа: используйте :: символ

простой пример модуля:

module MySampleModule
  CONST1 = "some constant"

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

как использовать методы внутри модуля:

puts MySampleModule.method_one(1) # prints: 3

как использовать константы модуля:

puts MySampleModule::CONST1 # prints: some constant

Некоторые другие соглашения о модулях:
Использовать один модуль в файле (например, классы ruby, один класс на файл ruby)

4 голосов
/ 23 марта 2015

Итог: модуль представляет собой нечто среднее между статическим / служебным классом и миксином.

Миксины - это многократно используемые части «частичной» реализации, которые можно комбинировать (или составлять) в режиме «смешивать и сочетать», чтобы помочь в написании новых классов. Конечно, эти классы могут иметь собственное состояние и / или код.

1 голос
/ 28 октября 2017

Класс

Когда вы определяете класс, вы определяете план для типа данных. класс содержит данные, имеет метод, который взаимодействует с этими данными и используется для создания экземпляров объектов.

Модуль

  • Модули - это способ группировки методов, классов и констант.

  • Модули дают вам два основных преимущества:

    => Модули предоставляют пространство имен и предотвращают конфликты имен. Пространство имен помогает избежать конфликтов с функциями и классами с тем же именем, которые были написаны кем-то другим.

    => Модули реализуют смешанную установку.

(включая модуль в Klazz дает экземпляры доступа Klazz к модулю методы. )

(расширить Klazz с помощью Mod, предоставив классу Klazz доступ к методам Mods.)

0 голосов
/ 29 мая 2018

Во-первых, некоторые сходства, которые еще не были упомянуты. Ruby поддерживает открытые классы, но модули также открыты. В конце концов, Class наследует от Module в цепочке наследования Class, поэтому класс и Module имеют похожее поведение.

Но вы должны спросить себя, какова цель наличия класса и модуля на языке программирования? Предполагается, что класс является планом для создания экземпляров, а каждый экземпляр представляет собой реализованный вариант плана. Экземпляр - это просто реализованная вариация проекта (Класса). Естественно, что классы функционируют как создание объектов. Кроме того, поскольку иногда мы хотим, чтобы один проект был получен из другого проекта, классы предназначены для поддержки наследования.

Модули не могут быть созданы, не создают объекты и не поддерживают наследование. Помните, что один модуль НЕ наследуется от другого!

Так в чем же смысл наличия модулей на языке? Одно из очевидных применений модулей - создание пространства имен, и вы заметите это и на других языках. Опять же, что хорошо в Ruby, так это то, что Модули можно открывать снова (так же, как Классы). И это большое применение, когда вы хотите повторно использовать пространство имен в разных файлах 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

Но нет наследования между модулями:

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>

Модуль Apple не наследовал никаких методов от модуля Green, и когда мы включили Apple в класс Fruit, методы модуля Apple были добавлены в цепочку предков экземпляров Apple, но не методы метода Green, хотя модуль Green был определен в модуле Apple.

Так как же нам получить доступ к зеленому методу? Вы должны явно включить его в свой класс:

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

Но у Ruby есть еще одно важное применение для модулей. Это средство Mixin, которое я опишу в другом ответе на SO. Подводя итог, можно сказать, что миксины позволяют определять методы в цепочке наследования объектов. С помощью миксинов вы можете добавлять методы в цепочку наследования экземпляров объектов (include) или singleton_class класса self (extension).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...