Ruby:在类中嵌套类与模块中的嵌套类相同吗?

时间:2011-11-01 16:47:08

标签: ruby oop nested-class

在Ruby中,可以声明像

这样的类
class A
    class B
    end
end

然后实例化内部类,如A::B.new

BA有某种特殊关系(在Java中是这种情况)还是A只是它的命名空间?换句话说,在类中嵌套一个类与在模块中嵌套它一样吗?

4 个答案:

答案 0 :(得分:2)

这是你应该真正启动irb并尝试它的那个时代之一。

是的,可以在另一个类中定义一个类。由于类的超类是模块(即类扩展模块),它们几乎可以完成模块所能完成的所有操作。一个值得注意的例外是你不能include(混合)一个类。

也就是说,实际使用这种设计模式的理由很少。 A和B更可能被视为兄弟姐妹。在脸部呈蓝色之前,不需要任意命名空间。如果你的深度超过3级,请停止并考虑重构。

此示例的更好设计模式可能是:

module Alphabet
  class A; end
  class B; end
end

对于更复杂的东西,使用Mixins继续很好地工作:

module Animals
  class Dog
    include Walking
  end

  module Walking
    # some methods pertaining to the ability to walk
  end
end

答案 1 :(得分:1)

是的,它与模块中的嵌套基本相同。嵌套类与它嵌套的类没有任何特殊关系。

答案 2 :(得分:1)

是的,......不。模块无法实例化,而类可以实例化,因此在模块中嵌套类与使用嵌套在类中的类之间存在差异。

例如:你不能在这里实例化福特的对象(即眼镜蛇,F-150,野马等),因为你无法实例化一个模块。

         `module Ford
            class Engine
              ...
            end
          end`

但是可以拥有类Ford的实例以及使用嵌套类的Ford引擎实例:

       `class Ford
           class Engine
             @@actions = ['list', 'find', 'add', 'quit']
             def self.actions; @@actions; end
           end

           def self.truck_exists?
             #Some more stuff here
           end
        end` 

答案 3 :(得分:0)

类(和模块)有不同的用法:

  • 命名空间:在另一个类(或模块)中定义类(或模块)时,必须在定义类之外使用不同的符号来到达内部类或模块。
  • 实例模板:模块和类的行为完全(大多数情况下)不同。
  • 继承:您可以扩展一个类,因此您可以继承其所有属性和方法,这些属性和方法也适用于模块。或者,您可以包含一个模块(不是:类),以将其方法(和属性)添加到您的范围。 Ruby通过混合类层次结构中的模块来玩这里的技巧。

因此,在使用名称空间的上下文中,它们是相同的。但是我会一直使用模块(仅限),但这更像是一种风格问题。关于这个主题的最好的书是我认为Paolo Perrotta的“Metaprogramming Ruby”。