Разница между классом и модулем



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



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

736   10  

10 ответов:

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

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

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

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

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

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

классы просто похожи на классы Java.

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

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

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


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

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

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

Mixins-это многоразовые части "частичной" реализации, которые могут быть объединены (или составлены) в стиле mix & match, чтобы помочь написать новые классы. Эти классы могут дополнительно иметь свое собственное состояние и / или код, конечно.

источник (вы можете узнать характеристики модуля оттуда)

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

класс

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

модуль

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

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

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

    => модули реализуют средство mixin.

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

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

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

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

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

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

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

в java минимальная единица является классом, вы не можете иметь функцию вне класса. Однако в ruby это возможно (например, python).

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

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

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

правила о модулях в ruby:
- Имена модулей являются UpperCamelCase
- константы внутри модулей-это все шапки (это правило одинаково для всех констант ruby, не специфичных для модулей)
- методы доступа: использование . оператор
- константы доступа: use:: symbol

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

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)

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

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

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

тогда какой смысл иметь модули в языке? Один очевидное использование модулей-это создание пространства имен,и вы заметите это и с другими языками. Опять же, что здорово в 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 не унаследовал никаких методов от зеленого модуля, и когда мы включили Apple в класс Fruit, методы Модуль Apple добавляются в цепочку предков экземпляров Apple, но не методы зеленого модуля, даже если зеленый модуль был определен в модуле Apple.

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

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

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

Comments

    Ничего не найдено.