Java has three different kinds of "methods": instance methods, static methods and constructors. Ruby only has one: instance methods.
In Java, static methods must behave differently from instance methods, because classes aren't objects. They have no class, therefore no superclass, so there is nothing to override. In Ruby, classes are objects just like any other object, they have a class, which can have a superclass, and thus subclasses can override superclass methods.
Note: you may have heard about class methods or singleton methods in Ruby. That's a lie. Well, okay, not a lie. It's a convenient shorthand we use, because "class method" is easier to pronounce than "regular instance method of the class object's singleton class" … but that's precisely what it is. There are no class methods.
In Ruby, every object can have methods of its own. These are called "singleton methods". Classes are objects like any other object, so they can have singleton methods, too. When the object a singleton method belongs to is a class, we call that method a class method. But that's just what we call it, there is no difference between a class method and a singleton method.
Actually, in Ruby, every object has a singleton class. The singleton class is in a 1:1 relation with the object: the object has exactly one singleton class and each singleton class has exactly one instance, its object. So, when I said above that objects can have methods and those methods are called singleton methods? Well, that was a lie, too. Singleton methods are really just standard instance methods, which happen to be defined in the singleton class of an object, and thus can be called only on that object (because that object is the only instance of its singleton class).
So, when a method is defined in a singleton class, we call it a singleton method and when the singleton class belongs to a class, we call it a class method, but it's all just instance methods. (BTW: modules work the same way. In that case, they are called module methods or sometimes "module functions".)
The class
pointer of an object always points to its singleton class. The actual class of an object is then the superclass
of the singleton class, i.e. the singleton class's superclass
pointer points to the actual class of the object. (Unless there are mixins, which become superclasses of the class they are mixed into, so if you mix a module into a singleton class, the module becomes the superclass of the singleton class, and the old superclass becomes the superclass of the module, or rather its include proxy class.)
What this means is that method lookup, which is the most often performed operation in an OO language, becomes really simple and really fast: grab the object, grab its class
pointer, see if the method is there, grab the superclass pointer, see if the method is there, grab the superclass pointer … until you found the method.
It does mean that reflection gets a little more complex, but reflection is not a performance-critical operation. For example, if you ask an object for its class, you can't simply return the class
pointer, as that would always be its singleton class and thus not very informative. You have to get the superclass, and the superclass's superclass and so on, until you end up at a class which is not a singleton class or an include proxy class.
But method lookup itself is very simple, and super
always does what you expect.
In particular, when you create a new class, the singleton class of the superclass becomes the superclass of the singleton class of the subclass, so that "class methods" are inherited just as you would expect.
So, to recap: while Java has three different kinds of "methods" with different inheritance behavior (instance methods get inherited, static methods don't, constructors get inherited but have this super
calling restriction), Ruby has only one. It has, however, three different kinds of classes: regular classes, singleton classes, and include proxy classes (created as proxies for mixins, when mixing a module into a class). The latter two are also called "virtual classes" inside of YARV, the most widely-used Ruby implementation.
One last thing: there are also so-called "global methods", sometimes called "global procedures" or "global functions". Again, as you probably guessed already, these don't exist. When you define a method outside of any class, it implicitly becomes a private instance method of Object
and thus available for every object.
[I ignored two things here: BasicObject
and prepend
. These complicate matters somewhat, especially the latter. But the main mental model remains.]