上周,我们学到了一些关于单子类的重要知识:类方法是一个类的单子类的实例方法。不过,让我们退一步来说--这与extend ?
我们已经知道 include将一个模块插入到类的祖先链中,就在该类的后面,includes 。 prepend在它之前插入一个模块。那么,extend 也会将一个模块插入祖先链,但它是在类的单子类(而不是类本身)的祖先链上这样做的。
module ExampleModule ; end
class ExampleClass
extend ExampleModule
end
ExampleClass.ancestors
=> [ExampleClass, Object, Kernel, BasicObject]
ExampleClass.singleton_class.ancestors
=> [#<Class:ExampleClass>, ExampleModule, #<Class:Object>,
#<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
#<Class:ExampleClass> 语法意味着它是ExampleClass 的单子类。我们可以看到ExampleModule 被插入到ExampleClass的单子类的祖先链中。
让我们把这与我们所学到的关于单子类的知识结合起来--一个类的单子类的实例方法就是该类的类方法。所以说我们有一个定义在ExampleModule 上的实例方法:
module ExampleModule
def example_module_instance_method
"This is an instance method defined on ExampleModule"
end
end
如果我们在extend ExampleModule ,它就会成为ExampleClass 的一个类方法:
class ExampleClass
extend ExampleModule
end
ExampleClass.example_module_instance_method
=> "This is an instance method defined on ExampleModule"
如果我们在同一个ExampleModule ,而不是使用include ,那么这个方法就仍然是一个实例方法:
class ExampleClass
include ExampleModule
end
ExampleClass.new.example_module_instance_method
=> "This is an instance method defined on ExampleModule"
很好!我们现在已经学会了三种在类中使用模块代码的方法: