Java and C# are definitely not from the Smalltalk family. Alan Kay even said that when he created OOP he did not have anything like Java or C++ in mind. Java, C#, and C++ all interpret OOP in pretty much the same way.
Languages like Smalltalk and Ruby have a radically different model that is based on message passing. In C++ classes are essentially namespaces for methods and state. Method invocations are bound at compile time. Smalltalk does not bind a "method call" until runtime. The result of this is that in C++
foo->bar
is compiled to mean "call the bar method on the foo object." If bar is non virtual, I'd imagine that the address of the bar method is specifically referenced.
In Smalltalk
foo bar
means "send the message bar to the foo object." foo
can do whatever it wants with this message when it arrives. The default behavior is to call the method named bar
, but that is not required. This property is exploited in Ruby for ActiveRecord column accessors. When you have an ActiveRecord object and you send it the name of a column in its database table as a message, if there is no method with that name defined, it checks to see if there is a column by that name on the table and if there is returns the value.
Message passing might seem like a tiny, irrelevant detail, but out of it, the rest of OOP easily flows.
"OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them." -- Alan Kay, creator of Smalltalk