你能告诉我应该在哪里使用模块和哪些类?我的意思是Ruby中模块的可用性和适用性原则是什么?
答案 0 :(得分:1)
模块是方法和常量的集合。他们无法生成实例。类可以生成实例(对象),并具有每实例状态(实例变量)。 模块可以混合到类和其他模块中。混合模块的常量和方法混合到该类中,增强了类的功能。但是,类不能混合到任何东西中。 类可以从另一个类继承,但不能从模块继承。 模块可能不会从任何东西继承。 - Ruby FAQ 的
类是可靠的抽象,只有重要的东西,模块是容器,可以给我信息或服务,而且可以是一个保持奇点的地方。例如,我们可以对害羞的人进行分类,胆怯是这种分类的单一性。 ShyPeople可能是一个类,而Timidity是ShyPeople类中的一个模块。
'重要的是什么?','它是模块的方法还是类'方法?'或者“它会是一个班级还是一个模块?”是只有经验和RL的类比可以帮助你的问题。有关详细信息,我建议您阅读和编码:)
答案 1 :(得分:0)
我的简单经验法则是,如果我需要保持对象的内部状态,例如创建实例变量,我将使用一个类。
我将模块用于其他一切。这包括命名空间,mixins和实用程序对象。
答案 2 :(得分:0)
本质上,Ruby模块就像一个类,但没有对象的工厂部分。通常,Ruby开发人员使用模块来存储必须由多个类使用的方法组。除其他外,这是避免使用子类的一种很好的方法,它是非常反rubyist模式。
无论如何,这几乎是一个哲学问题,人们无法在短时间内正确回答。也许你应该尝试阅读一本关于Ruby基础知识的书(例如,Eloquent Ruby)。
答案 3 :(得分:0)
类 ARE 模块。不同之处在于可以实例化一个类。
两者的用法实际上取决于你的类/模块的使用方式,它代表什么,......
这个问题没有最终答案。在任何情况下(imho),这是你通过阅读和编写代码,学习成语,设计模式,...来学习的东西。
答案 4 :(得分:0)
在ruby中,模块由方法,变量和常量组成,类似于类,只是缺乏实例化的能力。
模块通常包含在类中或在类中扩展,具体取决于您希望如何公开和使用它包含的方法。如果您希望它的方法,变量和常量可以在您包含它的类的每个对象中使用,则包含一个模块。如果您希望它的方法,变量和常量可用于类而不扩展模块对于班级的实例。
Ruby类使用单继承,也就是说,一个类只有一个父类/超类。但是,红宝石可以帮助你实现"通过在类中包含模块来模仿多重继承,这个概念称为mixins。
答案 5 :(得分:0)
模块用作命名空间和mixins。 Ruby不支持多重继承。但是,有些情况下,类会通过获取多个其他类中定义的方法而受益。通过使用名为module的构造可以实现这一点。模块有点类似于类,除了它不支持继承或实例化。它主要用作存储多种方法的容器。使用模块的一种方法是在类中使用include或extend语句。这样,该类就可以访问模块中定义的所有方法和对象。据说该模块在课堂上混合使用。因此,mixin只是一个类中包含的模块。单个模块可以混合在多个类中,单个类可以混合在多个模块中;因此,mixin功能消除了Ruby单一继承模型所施加的任何限制。
所有模块都是Module类的实例。
module Foo
end
Foo.instance_of? Module # Output: => true
在以下示例中,JapaneseGreetings模块包含在Person类中(作为mixin)。
module JapaneseGreetings
def hello
puts "Konnichiwa"
end
def goodbye
puts "Sayōnara"
end
end
class Person
include JapaneseGreetings
end
p = Person.new
p.hello # Output: Konnichiwa
p.goodbye # Output: Sayōnara
所有类都是名为Class的内置类的实例?好吧,Class是Module的子类(另一个内置类)。
Class.superclass # Output: => Module
用于操作类的大多数内置方法都在Module类中定义。
Module.instance_methods(false)
=> [:<=>, :module_exec, :class_exec, :<=, :>=, :==, :===, :include?, :included_modules, :ancestors, :name,
:public_instance_methods, :instance_methods, :private_instance_methods, :protected_instance_methods, :const_get,
:constants, :const_defined?, :const_set, :class_variables, :class_variable_get, :remove_class_variable,
:class_variable_defined?, :class_variable_set, :private_constant, :public_constant, :singleton_class?,
:deprecate_constant, :freeze, :inspect, :module_eval, :const_missing, :prepend, :method_defined?, :class_eval,
:public_method_defined?, :private_method_defined?, :<, :public_class_method, :>, :protected_method_defined?,
:private_class_method, :to_s, :autoload, :autoload?, :instance_method, :public_instance_method, :include]
标准做法是在超类中实现“通用”代码(可以在不同的上下文中使用),并在子类中添加额外的特化。一个例子是Class类如何从Module类继承所有上述实例方法,并实现另外三种方法。
Class.instance_methods(false)
=> [:new, :allocate, :superclass]
allocate方法分配内存并创建类的新“空”实例,而不调用initialize方法。新方法调用allocate,然后在新创建的对象上调用initialize方法。对于超类,它返回给定类的超类的名称。
在他的“Ruby编程语言”一书中,Yukihiro Matsumoto(Ruby的创建者,AKA Matz)演示了新方法如果用Ruby编写的话会是什么样子:
def new(*args)
o = self.allocate # Create a new object of this class
o.initialize(*args) # Call the object's initialize method with our args
o # Return new object; ignore return value of initialize
end
简而言之,我们可以说类是具有两个重要额外功能的模块:继承和实例化。另一个区别是,与模块不同,类不能用作mixins。