ruby中的类和模块

时间:2012-07-18 14:28:48

标签: ruby class module

你能告诉我应该在哪里使用模块和哪些类?我的意思是Ruby中模块的可用性和适用性原则是什么?

6 个答案:

答案 0 :(得分:1)

模块是方法和常量的集合。他们无法生成实例。类可以生成实例(对象),并具有每实例状态(实例变量)。 模块可以混合到类和其他模块中。混合模块的常量和方法混合到该类中,增强了类的功能。但是,类不能混合到任何东西中。 类可以从另一个类继承,但不能从模块继承。 模块可能不会从任何东西继承。 - Ruby FAQ

类是可靠的抽象,只有重要的东西,模块是容器,可以给我信息或服务,而且可以是一个保持奇点的地方。例如,我们可以对害羞的人进行分类,胆怯是这种分类的单一性。 ShyPeople可能是一个类,而Timidity是ShyPeople类中的一个模块。

'重要的是什么?','它是模块的方法还是类'方法?'或者“它会是一个班级还是一个模块?”是只有经验和RL的类比可以帮助你的问题。有关详细信息,我建议您阅读和编码:)

答案 1 :(得分:0)

我的简单经验法则是,如果我需要保持对象的内部状态,例如创建实例变量,我将使用一个类。
我将模块用于其他一切。这包括命名空间,mixins和实用程序对象。

some basic Namespacing and Mixin info

答案 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。