(A C++ example, that is) // "Toy" is an abstract base class. class Toy { public: virtual void playWith() = 0; // Note the shiny "= 0". }; // "Cap''''''Gun" is one of the concrete classes. class Cap''''''Gun: public Toy { public: virtual void playWith() { /* Pow! */ } }; // "Football" is the other concrete class. class Football: public Toy { public: virtual void playWith() { /* Punt! */ } }; // And "Snot''''''Nose''''''Kid::enjoy(Toy&)" is a PolymorphicFunction class Snot''''''Nose''''''Kid { // Note how the type used is that of the base class. public: void enjoy(Toy& t) { t.playWith(); } }; void f() { CapGun gun; Football ball; Snot''''''Nose''''''Kid kid; kid.enjoy(gun); kid.enjoy(ball); } The point here is that a "Toy" is just a concept, a certain kind of thingy, not a tangible thingy. (Or, in OOP terms, "Toy" is purely abstract, a class of objects, not a concrete object.) There is no reasonable implementation for Toy::playWith(). How do you "play" with a toy that you know nothing about? You can look at it... fidget with it... but in the end the way you use a Cap''''''Gun is nothing like the way you use a Football, even though they are both Toys. Observe: void g() { Toy toy; // Compile-time error! You can't instantiate a Toy // directly. Snot''''''Nose''''''Kid kid; // This kid doesn't know how to play with such a generic toy, // so it's a good thing the compiler didn't let him become // frustrated. kid.enjoy(toy); } Why not just use some generic mechanism, such as casting or templates? Well, consider the following code: // Note that this doesn't inherit from "Toy". class Real''''''Gun { public: void playWith() { /* Yikes! */ } }; void h() { Real''''''Gun gun; Snot''''''Nose''''''Kid kid; kid.enjoy(gun); // Compile-time error! Kid's shouldn't // play with Real Guns! } So, remember kids: Every gun is a loaded gun, and tell an adult if you find a switch statement.