The idea is that in a static language like C# or Java, OO concepts are all bound in class hierarchies. So if you want polymorphism, you look at inheritance or a interface contract.
So if I have AdminUser
and ForumUser
, and I want to treat them the same way for the purposes of getting their username, I will implment a IUser
interface that has a method called GetUsername();
. If AdminUser
and ForumUser
both implement that interface, I can cast them to IUser
and call GetUsername()
.
On dynamic languages, polymorphism is accomplished by what the object actually does. You don't care if it is AdminUser
, ForumUser
, or FooUser
, what you care about is if the object has a GetUsername()
method.
This takes alot of overhead out of polymorphism and class heirarchies, because you don't have to explicitly design these relationships in, they can occur more naturally. It is a fundamentally different way about thinking of things that requires far less decision making up front, and far less work refactoring later on if you change your mind.
If I were to do the same thing in ruby, I would do
@user.username if @user.responds_to? :username
I dont care what kind of user it is, I don't even nessicarily care if it is even a user at all. All I care about is if it has a username. If I care more about the object then I will ask it more questions, but it is the idea that those questions happen when (and where) I need to ask them, and I only have to ask as many as I want to. In a "Class Oriented" language, it is far more rigid, if you want to do something like that you have specific choices that have to be done in a specific way. Either interface or inheritance explicitly defined in their classes at compiled time, with casting as the mechanism for actually treating the objects differently.