0

给定一个类 A 和一个模块 B,混合 B 的实例方法,以便它覆盖 A 的相应实例方法。

module B
  def method1
    "B\#method1"
  end

  def method2
    "B\#method2"
  end
end

class A
  def method1
    "A\#method1"
  end

  def method2
    "A\#method2"
  end

  # include B    does not override instance methods!
  #              (module gets mixed into the superclass)
end

puts A.new.method1   # want it to print out "B#method1"
puts A.new.method2   # want it to print out "B#method2"
4

2 回答 2

7

Module#include将模块M作为类的超类插入C。因此,您不能覆盖C' 中的方法M,而是相反:C' 的方法会覆盖M' 的方法。(从技术上讲,Ruby 并没有创建M的超类C,而是创建了一个不可见的Include 类 ⟦M′⟧,其方法表和常量表指向M的方法表和常量表,并使该类成为超类,但这种区别对于这个特殊的问题。)

在 Ruby 2.0 中,有一个新方法,Module#prepend顾名思义,它添加 M到的祖先C,换句话说,M创建.C

所以,简而言之:你不能,至少现在还不能。

于 2012-08-21T15:43:38.490 回答
0

您可以从包括之前删除每个B's 方法。AB

class A
  def method1
    "A\#method1"
  end

  def method2
    "A\#method2"
  end

  B.instance_methods(false).each { |method|
    remove_method(method) if instance_methods(false).include?(method)
  }
  include B
end

或从内部B

module B
  def method1
    "B\#method1"
  end

  def method2
    "B\#method2"
  end

  def self.append_features(mod)
    instance_methods(false).each { |method|
      mod.send(:remove_method, method) if mod.instance_methods(false).include?(method)
    }
    super
  end
end
于 2012-08-21T15:49:32.967 回答