By now, you've hopefully gained a solid appreciation for how powerful object-oriented languages are for modeling complex real-world situations. By way of review:
We can create our own user-defined types, also known as classes, to model objects of arbitrary complexity, as we discussed in Chapter 3.
We can arrange these types into class hierarchies to take advantage of the inheritance mechanism of OO languages, as we discussed in Chapter 5.
Through encapsulation and information hiding, we can shield client code from changes that we make to the private implementation details of our classes, as well as making objects responsible for ensuring the integrity of their own data, as we discussed in Chapter 4.
Classes can model the most complex of real-world concepts, particularly when we take advantage of collections, as we did when modeling the transcript attribute of the Student class in Chapter 6.
You might wonder how there could possibly be anything more left in our OO bag of tricks! However, as powerful as all of the preceding OO language features are, there is one more essential feature that we haven't yet spoken about, which ties them all together into an unbeatable package: a feature known as polymorphism.
Also, as with any technology, there are core concepts and then there are "special topics": things that you don't necessarily need to know when you're first setting out to use the technology, but which are valuable to know as you become adept with the basics. If you buy an expensive, professional-caliber camera, for example, you may initially be able to use it only as a "point-and-shoot" camera, letting the camera do all of the work of automatically determining how to adjust the lens to produce a quality picture. As your familiarity with the camera's features improves, however, you'll find yourself able to command the camera to do some pretty amazing things! Arming yourself with knowledge of such special object technology topics—the "icing" on the object "cake"—will enhance your ability to develop sophisticated OO applications.
In this chapter, you'll learn
How polymorphism allows the same message to be responded to differently by different types of objects
How programming constructs known as abstract classes and interfaces can be used to specify what an object's mission should be without going to the trouble of specifying the details of how the object is to carry out that mission, and also why we'd want to be able to do so
How an object can have a "split personality" by exhibiting the behaviors of two or more different types of object
Creative ways for an entire class of objects to easily and efficiently share data without breaking the spirit of encapsulation
How features can be defined that are associated with a class itself rather than with an instance of a class
How to define a constant whose value can't be changed once it's initially set