在Ruby类中向子节点发送方法?继承混乱

时间:2014-02-10 04:20:58

标签: ruby

我有以下代码:

class Bike 
  attr_reader :chain

  def initialize
    @chain = default_chain
  end

  def default_chain
    raise 'SomeError'
  end
end


class MountainBike < Bike
  def initialize
    super
  end

  def default_chain
    4
  end
end

mb = MountainBike.new
p mb.chain

在初始化时我们调用super,我希望调用超类的default_chain,因此要启动Exception。但是,似乎Bike类实际上调用了原始调用者的default_chain方法。那是为什么?

3 个答案:

答案 0 :(得分:1)

如上所述@BorisStitnicky你需要使用singleton_class。为了便于理解,您可以在这篇文章中找到信息:Understanding the singleton class when aliasing a instance method

答案 1 :(得分:0)

将同名方法放在子类中的重点是重载该方法。 即用新版本替换它。

代码将查看调用子类的任何方法的版本 - 在它开始查找方法的祖先链之前,因为子类是当前代码的 context

因此,即使该方法在超类中被引用...... ruby​​解释器仍将首先将您的子类的方法集视为主要上下文。

如果你还想打电话给父母一个 - 你也必须在你的default_chain方法中使用super。 或者将父类中的那个重命名为其他类,并仅从您的超类中调用它。

答案 2 :(得分:0)

在面向对象编程中,调用哪个方法完全由接收者和方法名称决定。

  • 在接收方:[{1}}实例上调用方法名称initializeMountainBike匹配并执行。
  • 在执行过程中,MountainBike#initialize被调用,super匹配,并被执行。
  • 在执行过程中,在隐式接收器Bike#initialize上调用方法名default_chain,这是self实例。 MountainBike匹配并执行。

如果在接收者(MountainBike#default_chain实例)的最后一步中调用Bike#default_chain,则意味着方法调用不仅取决于接收者和方法名称,还取决于上下文。这会使它变得太复杂,并且会破坏面向对象编程的目的。同样,面向对象编程的想法是方法调用完全由接收者和方法名称决定,而不是上下文