让Parent调用原始Method而不是覆盖的方法

时间:2014-04-24 17:25:15

标签: ruby oop

给出两个类

class A
  def method_a ()
    method_b()
  end

  def method_b ()
    puts "Comes from A"
  end
end

B继承自A

class B < A
  def method_a ()
    super()
  end

  def method_b ()
    puts "Comes from B"
  end
end

当我致电B.method_a时,结果将是:Comes from B。是否有可能告诉A调用method_b而不是覆盖我的Comes from A? (这样结果就是{{1}})

5 个答案:

答案 0 :(得分:0)

我不认为你可以直接做到这一点,不会破坏,但不会破坏inheritancetemplate pattern的目的,因为可能有C }类以及继承自A,并且您可能只想调用类method_b的{​​{1}}函数,因为它已被覆盖并且需要。

答案 1 :(得分:0)

你所要求的不被支持,因为它破坏了继承点。您可以做的是将实现拆分为两个方法 - 一个执行A实现method_b,一个不被覆盖,一个委托到该实现,可能被覆盖:

class A
  def method_a
    dont_override_me
  end

  def method_b
    dont_override_me
  end

  private
  def dont_override_me
    puts "Comes from A"
  end
end

class B < A
  def method_a 
    super
  end

  def method_b
    puts "Comes from B"
  end
end

答案 2 :(得分:0)

class A
  def method_a; comes_from_A end
  def method_b; puts "Comes from A" end
  alias comes_from_A method_b
end

class B < A
  def method_a; super end
  def method_b; puts "Comes from B" end
end

答案 3 :(得分:0)

您可以按如下方式修改子类:

class B < A
  def method_a
    self.class.send(:remove_method, :method_b)
    super()
    self.class.send(:alias_method, :method_b, :method_b_alias)
  end

  def method_b
    puts "Comes from B"
  end

  alias_method :method_b_alias, :method_b
end

b = B.new

b.method_b
  # Comes from B
b.method_a
  # Comes from A
b.method_b
  # Comes from B

创建子类时会创建别名:method_b_alias。每当method_a的实例调用B时,B方法method_b的{​​{1}}被移除,super' s A找不到它并使用自己的method_a代码(因为method_a的{​​{1}}(A)的接收者是{{method_a的实例1}}。)self返回后,B用于再次使super的{​​{1}}可用于alias_method的实例。

我们需要使用Module#remove_method而不是Module#undef_method。如果使用后者,B的{​​{1}}会在发现method_a没有该方法后放弃寻找B

如果您愿意,可以更改两行以使用关键字A而不是method_a

method_b

答案 4 :(得分:0)

没有相当于C ++的A::method_a

但你可以这样做

class A
  def method_a
    A.instance_method(:method_b).bind(self).call
  end

  def method_b
    puts "Comes from A"
  end
end

class B < A
  def method_a
    super
  end

  def method_b
    puts "Comes from B"
  end
end

method_a中发生的事情是,我们正在检索A method_b的实施并直接调用它。

虽然

首先使用继承,但这确实有点飞