简体   繁体   中英

Sending method to child in Ruby class? Inheritance confusion

I have the following code:

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

When in the initialization we call super, I would expect the default_chain of the super class to be called, and therefore the Exception to be launched. However, it seems that the Bike class actually goes and calls the default_chain method of the original caller. Why is that?

As said @BorisStitnicky you need to use singleton_class. For more understanding, in this post you may find info: Understanding the singleton class when aliasing a instance method

The point of putting a same-named method in a sub-class is to overload that method. ie to replace it with your new version.

The code will look at the calling sub-class's version of any method - before it starts looking up the ancestry chain for a method, because the sub-class is the context of the current code.

So even though the method is referred-to in the superclass... the ruby interpreter will still first look at your sub-class's set of method as the main context.

If you also want to call the parent's one - you must use super in your default_chain method too. Alternatively rename the one in the parent class to something else and call it from your superclass only.

In object oriented programming, which method is called is solely determined by the receiver and the method name.

  • Method name initialize is called on the receiver: MountainBike instance, for which MountainBike#initialize matches, and is executed.
  • Within the execution, super is called, for which Bike#initialize matches, and is executed.
  • Within the execution, method name default_chain is called on the implicit receiver self , which is the MountainBike instance. MountainBike#default_chain matches, and is executed.

If Bike#default_chain were to be called in the last step on the receiver ( MountainBike instance), it would mean that method calling would depend not only on the receiver and the method name, but also on the context. That would make it too complicated, and would defeat the purpose of object oriented programming. Again, the idea of object oriented programming is that method call is solely determined by the receiver and the method name, not the context .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM