Polymorphism
As the examples above illustrate, messages in Objective-C appear in the same syntactic positions as
function calls in standard C. But, because methods “belong to” an object, messages behave differently
than function calls.
In particular, an object can be operated on by only those methods that were defined for it. It can’t
confuse them with methods defined for other kinds of objects, even if another object has a method
with the same name. This means that two objects can respond differently to the same message. For
example, each kind of object sent a display message could display itself in a unique way. A Circle
and a Rectangle would respond differently to identical instructions to track the cursor.
This feature, referred to as polymorphism, plays a significant role in the design of object-oriented
programs. Together with dynamic binding, it permits you to write code that might apply to any
number of different kinds of objects, without you having to choose at the time you write the code
what kinds of objects they might be. They might even be objects that will be developed later, by other
programmers working on other projects. If you write code that sends a display message to an id
variable, any object that has a display method is a potential receiver.
Dynamic Binding
A crucial difference between function calls and messages is that a function and its arguments are
joined together in the compiled code, but a message and a receiving object aren’t united until the
program is running and the message is sent. Therefore, the exact method that’s invoked to respond
to a message can only be determined at runtime, not when the code is compiled.
The precise method that a message invokes depends on the receiver. Different receivers may have
different method implementations for the same method name (polymorphism). For the compiler to
find the right method implementation for a message, it would have to know what kind of object the
receiver is—what class it belongs to. This is information the receiver is able to reveal at runtime when
it receives a message (dynamic typing), but it’s not available from the type declarations found in
source code.
The selection of a method implementation happens at runtime. When a message is sent, a runtime
messaging routine looks at the receiver and at the method named in the message. It locates the
receiver’s implementation of a method matching the name, “calls” the method, and passes it a pointer
to the receiver’s instance variables. (For more on this routine, see “How Messaging Works” (page
75).)
The method name in a message thus serves to “select” a method implementation. For this reason,
method names in messages are often referred to as selectors.
This dynamic binding of methods to messages works hand-in-hand with polymorphism to give
object-oriented programming much of its flexibility and power. Since each object can have its own
version of a method, a program can achieve a variety of results, not by varying the message itself,
but by varying just the object that receives the message. This can be done as the program runs; receivers
can be decided “on the fly” and can be made dependent on external factors such as user actions.
When executing code based upon the Application Kit, for example, users determine which objects
receive messages from menu commands like Cut, Copy, and Paste. The message goes to whatever
object controls the current selection. An object that displays text would react to a copy message
differently from an object that displays scanned images. An object that represents a set of shapes
Object Messaging 19
2008-02-05 | © 2008 Apple Inc. All Rights Reserved.
CHAPTER 1
Objects and Classes