There's one last wrinkle to class inheritance, and it's fairly
obscure.
Within a class definition, you can change the visibility of a method
in an ancestor class. For example, you can do something like:
class Base
def aMethod
puts "Got here"
end
private :aMethod
end
class Derived1 < Base
public :aMethod
end
class Derived2 < Base
end
|
In this example, you would be able to invoke
aMethod
in
instances of class
Derived1
, but not via instances of
Base
or
Derived2
.
So how does Ruby pull off this feat of having one method
with two different visibilities? Simply put, it cheats.
If a subclass changes the visibility of a method in a parent, Ruby
effectively inserts a hidden proxy method in the subclass that invokes
the original method using
super
. It then sets the visibility
of that proxy to whatever you requested. This means that the code:
class Derived1 < Base
public :aMethod
end
|
is effectively the same as:
class Derived1 < Base
def aMethod(*args)
super
end
public :aMethod
end
|
The call to
super
can access the parent's method regardless of
its visibility, so the rewrite allows the subclass to override its
parent's visibility rules. Pretty scary, eh?