在Ruby中覆盖继承模块的方法

时间:2016-04-23 20:33:18

标签: ruby oop

我有这个模块

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

1 个答案:

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