A method has automatic access only to the receiver’s instance variables. If it requires information about a
variable stored in another object, it must send a message to the object asking it to reveal the contents of
the variable. The primaryColor and isFilled methods shown above are used for just this purpose.
See “Defining a Class” (page 35) for more information on referring to instance variables.
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 object, 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 Messaging in the Objective-C Runtime Programming Guide.)
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.
18
Object Messaging
2010-07-13 | © 2010 Apple Inc. All Rights Reserved.
CHAPTER 1
Objects, Classes, and Messaging