我有这个模块
module MyModule
def self.foo()
puts "A"
end
end
这个mixin类
class ParentClass
include MyModule
...other code
end
我可以覆盖像这样的子类中的foo
方法,还是有更好的方法?
class ChildClass < ParentClass
def self.foo()
puts "B"
end
... other code
end
答案 0 :(得分:1)
你不能直接include
类方法:
module MyModule
def self.foo() puts "A" end
end
class ParentClass
include MyModule
end
ParentClass.methods.include?(:foo)
#=> false
ParentClass.instance_methods.include?(:foo)
#=> false
而是使用Object#extend,它将MyModule
中的实例方法转换为ParentClass
中的类方法:
module MyModule
def foo() puts "A" end
end
class ParentClass
extend MyModule
end
ParentClass.methods.include?(:foo)
#=> true
ParentClass.foo
A
class ChildClass < ParentClass
def self.foo() puts "B" end
end
ChildClass.foo
B
所以,您可能会问,在模块中使用类方法有什么意义?当模块不用作mixin时,它们可以存在,或者具有实例和类方法的组合。模块的类方法只是辅助函数:
module A
def self.say
puts "It's a cat."
end
def say
puts "It's a dog."
end
end
class B
include A
end
A.say
It's a cat
B.new.say
It's a dog.
我的印象是,大多数包含类方法的模块往往不包含实例方法;也就是说,它们不会被用作混合。如果我错了,建议读者纠正我。
include
某些实例方法和extend
其他方法的常用方法是使用回调Module#included:
module A
def a; end
def self.included(klass)
klass.extend B
end
module B
def b; end
end
end
class C
include A
end
C.instance_methods.include?(:a)
#=> true
C.methods.include?(:b)
#=> true