何时使用嵌套在模块中的嵌套类和类?
我很熟悉何时使用子类和模块,但最近我已经看到这样的嵌套类:
class Foo class Bar # do some useful things end end
以及嵌套在模块中的类如下所示:
module Baz class Quux # more code end end
无论是文档和文章都很less,或者我对这个主题没有足够的了解,没有find正确的search条件,但我似乎无法find关于这个主题的很多信息。
有人可以提供关于为什么/何时使用这些技术的post的例子或链接?
其他的OOP语言具有内部类 ,如果不绑定到上一级的类,就不能实例化。 例如,在Java中,
class Car { class Wheel { } }
只有Car
类中的方法才能创buildWheel
。
Ruby没有这种行为。
在Ruby中,
class Car class Wheel end end
不同于
class Car end class Wheel end
只有在Wheel
与Car::Wheel
。 这个名字上的差异可以让程序员明白,Car :: Wheel类只能代表一个车轮,而不是一般的车轮。 在Ruby中嵌套类的定义是一个优先select的问题,但是它的目的就在于它强化了两个类之间的契约,并且这样做传递了更多关于它们及其用法的信息。
但是对于Ruby解释器来说,这只是名称上的差别。
至于你的第二个观察,嵌套在模块内部的类通常用于命名空间的类。 例如:
module ActiveRecord class Base end end
不同于
module ActionMailer class Base end end
虽然这不是嵌套在模块内部的类的唯一用法,但它通常是最常见的。
在Ruby中,定义嵌套类与在模块中定义类相似。 它实际上并不强制类之间的关联,它只是为常量创build一个名称空间。 (类和模块名称是常量。)
被接受的答案是不正确的。 1在下面的例子中,我创build了一个不含封闭类的实例的词法封闭类的实例。
class A; class B; end; end A::B.new
其优点与模块相同:封装,仅在一个地方使用的分组代码,以及使代码更靠近使用的地方。 一个大型的项目可能会有一个外部模块在每个源文件中反复出现,并且包含大量的类定义。 当各种框架和图书馆代码都做到这一点时,他们每个人只能向顶层提供一个名称,从而减less冲突的机会。 平淡无奇,但是这就是为什么他们被使用。
使用一个类而不是一个模块来定义外部命名空间在一个单一文件的程序或脚本中可能是有意义的,或者如果你已经使用了顶层类的东西,或者如果你实际上要添加代码来链接类在真正的内部类风格。 Ruby没有内部类,但没有阻止你在代码中创build相同的行为。 从内部对象引用外部对象仍然需要从外部对象的实例中点入,但嵌套类将表明这是您可能正在做的事情。 一个精心模块化的程序可能总是首先创build封闭的类,并且可能合理地用嵌套类或内部类进行分解。 你不能在模块上调用new
。
你甚至可以使用通用模式来处理那些命名空间不是非常需要的脚本,只是为了好玩和练习。
#!/usr/bin/env ruby class A class Realwork_A ... end class Realwork_B ... end def run ... end self end.new.run
你可能想用这个将你的类分组到一个模块中。 sorting的命名空间的东西。
例如Twitter的gem使用名称空间来实现这一点:
Twitter::Client.new Twitter::Search.new
所以Client
和Search
类都在Twitter
模块下面。
如果你想检查源代码,这两个类的代码可以在这里和这里find。
希望这可以帮助!
除了以前的答案: Ruby中的模块是一个类
$ irb > module Some end => nil > Some.class => Module > Module.superclass => Object