Imagine that you have a Shape class hierarchy (like the one we have been using).
Imagine that each subclass has a perimeter() method that computes the object's perimeter.
The Shape class has an abstractperimeter() method.
Imagine a Shape identifier, shapeRef, referring to an object in any 1 of Shape's subclasses.
Then, an expression shapeRef.perimeter() is evaluated at runtime to see which perimeter() method to
invoke.
The perimeter method of the subclass associated with the actual object referred to by shapeRef will be invoked
(e.g., Equalateral, if shapeRef refers to an object of class Equalateral).
Screen refresh
Imagine that you have a video game applet that has several kinds of entities interacting on the screen: Martians,
Venutians, Plutonians, Spaceships, LaserBeams, and one all-powerful PowderedMilkToastMan.
Each of these entities has a position that changes with time.
Periodically, you want to repaint the screen with your array of screen objects.
You endow each object with a draw method (used to render itself),;
They are all subclasses of an abstract class, say, ScreenEntities, that has an abstractdraw method.
You have a method that iterates through the array of ScreenEntities, sending each the draw message.
Each object responds to the draw message in a manner appropriate to its class.
If you add a new kind of object, say a lowly BeefTaloBoy, then all you have to do to fit it into your scheme
is to endow the BeefTaloBoy class with a draw method.
No change to your screen repainting method is needed.
Via polymorphism, 1 method invocation can cause different actions to occur depending on the type of the
object receiving the message.