Ruby inheritance -Access modifiers and misconceptions behind them
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
endclass Porsche < Car; end;Car.new.mileage
Porsche.new.mileageirb(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
endclass Porsche < Car
def call_porsche_mileage
mileage
end
endirb(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
endclass Porsche < Car
def call_porsche_mileage
mileage
end
endirb(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
endclass 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.