Ruby inheritance -Access modifiers and misconceptions behind them

Aditya Tiwari
2 min readJun 18, 2018

How does Public, Private and Protected behave in child class of inheritance?

In Ruby Private and Protected access modifiers behave differently in case of inheritance as compared to other languages like Java. Public behaves pretty much same.

Let’s not waste the time and discuss about them one by one with examples.

Public:

All public methods of parent class can be accessed in child class, it’s that simple!

class Car
def mileage
"I returns mileage of a #{self.class}"
end
end
class Porsche < Car; end;Car.new.mileage
Porsche.new.mileage
irb(main):001:0> Car.new.mileage
=> "I returns mileage of a Car"
irb(main):002:0> Porsche.new.mileage
=> "I returns mileage of a Porsche"

Private:

Just like public methods, All private methods of parent class is also available as private methods in child class. This behaviour is different than Java, In Java you can’t access private methods of parent class in child class.

class Car
def call_car_mileage
mileage
end
private def mileage
"I returns mileage of a #{self.class}"
end
end
class Porsche < Car
def call_porsche_mileage
mileage
end
end
irb(main):103:0> Car.new.call_car_mileage
=> "I returns mileage of a Car"
irb(main):104:0> Porsche.new.call_porsche_mileage
=> "I returns mileage of a Porsche"

Protected:

Protected is most misunderstood access modifier in Ruby, be with me, I can try to explain.

Protected methods can be accessed inside the child class just like private methods. For example:

class Car
def call_car_mileage
mileage
end
protected def mileage
"I returns mileage of a #{self.class}"
end
end
class Porsche < Car
def call_porsche_mileage
mileage
end
end
irb(main):103:0> Car.new.call_car_mileage
=> "I returns mileage of a Car"
irb(main):104:0> Porsche.new.call_porsche_mileage
=> "I returns mileage of a Porsche"

So, what’s the difference between Protected and Private?

Let’s try calling Protected method mileage directly on object.

irb(main):111:0> Porsche.new.mileage
NoMethodError: protected method `mileage' called for #<Porsche:0x007fc9922c97b0>

As you can see mileage is not available directly on object of class, now let’s try to call mileage on object of Porsche class from the inside the context where mileage is defined.

class Car
def call_milage
Porsche.new.mileage
end

protected
def mileage
"I returns mileage of a #{self.class}"
end
end
class Porsche < Car; end;irb(main):001:0> Car.new.call_milage
=> "I returns mileage of a Porsche"

As you can see Porsche.new.mileage is not working from outside but it is working when called in the context of class Car.

So, we can say that Protected methods behaves as Private when called from outside the context of defined class and behaves as Public when called from inside the context of defined class.

In my next post, I will talk more about the use case of Protected methods, meanwhile you can checkout my other similar posts.

--

--

Aditya Tiwari

Special love for Ruby. Love to talk Ruby in conferences and meetups, contact me for more info https://www.linkedin.com/in/aditya01933