RE: What is the purpose/uses of run-time polymorphism? Is dynamic binding only way to achieve run-time polymorphism?
Run-time polymorphism provides the ability to use late-binding. In other words the function called or the data member accessed is not determined until run-time and is based on the type that a variable references. Run-time polymorphism allows the support of inheritance and function overriding. On the flip side polymorphism uses early-binding to support features such as function overloading features that can be determined at compile-time.
Dynamic binding is one of several ways to achieve run-time polymorphism. There are various ways of implementing dynamic binding. Dynamic binding uses tables "binding" or maps linking names to memory locations. The memory locations can be the entry point to function or data location. These tables can be built during compilation or depending on the implementation could be constructed and modified at run-time each time an object of a new data type is created. In dynamic binding only a single map or table of bindings exists either as a global table or a separate table for each data type.
An alternative to dynamic binding is lexical binding. In lexical binding the map of name to memory location is associated with each variable instead of each data type as in dynamic binding. Lexical binding is commonly used in languages like lisp and scheme.