You did not get any satisfactory answers so far. This is done via dynamic dispatch
via the virtual method table
. In other word, the required flexibility is achieved throw indirect call: the address is found in the table, and, for different runtime types
, the address is different. The mechanism is explained here:
If you are not getting it, ask some follow-up question, I can explain fine detail.
For some advanced and indirectly related idea, please see my article: Dynamic Method Dispatcher
It does not explain OOP mechanism, but it discusses the problems of dynamic dispatch and parallels with this mechanism, in the section "Complement OOP or Abuse it?".