Looking at Object-Oriented Programming in the Context of Objective-C
The heart of the implementation of object-oriented programming consists of the objects themselves and the roles that they can play. With Objective-C, there is another point to notice about the implementation of the language; because it is a dynamic language, some of the work that would be done in the compile and build process for a language such as C++ is done at runtime. This means that the runtime environment, which, for all intents and purposes is the operating system, is a much bigger player than it is in other languages.
Differentiating Classes, Instances, and Objects
The first point to remember is that objects, classes, and instances are related but different concepts. These concepts exist in most object-oriented languages:
- Class—A class is what you write in your code. It typically consists of a header file (ending in .h) with an interface, as well as an implementation file (ending in .m) that provides the code to support the interface.
- Instance—At runtime, a class can be instantiated. That converts it from instructions in your program to an object that has a location in memory and that can function.
- Object—Object is a term that is commonly used in contexts where most people understand what is meant. The word can be used to refer to instances or classes, but most of the time, it refers to instances.
Understanding What Is Not an Object
Some basic types are declared in Foundation/Foundation.h. Each of these is implemented as a struct (NSDecimal), a typedef (NSUinteger), or an enum (NSComparisonResult). Sometimes these hide the actual implementation, such as this definition of NSInteger, which resolves to a long on a 64-bit application and to an int otherwise:
#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 typedef long NSInteger; #else typedef int NSInteger; #endif
Using these types makes your code more maintainable and portable than using native C types.
With the exception of basic types such as these, almost everything you deal with is an object. You will find some non-object entities in the Core Foundation framework and in specialized frameworks that often deal with low-level operations such as Core Animation.
Understanding the Three Purposes of Objects
Building on Smalltalk's structure, objects in Objective-C have three purposes and functions:
- State—Objects can contain state, which in practical terms means that they can contain data and references to other objects. In implementation and use, state usually consists of member variables, instance data, or whatever terminology you use.
- Receive messages—Objective-C objects can receive messages sent from other objects.
- Send messages—Objective-C can send messages to other objects.
- Communication between objects is via these messages, which are highly structured. This is covered in more detail in the "Messaging in Objective-C" section later in this hour, p. 73.
Data is encapsulated within objects in Objective-C. That means it is accessible only through messages. Objects cannot access another object's data (state) directly as can happen in other object-oriented languages. This is a general goal of all good object-oriented programming, but it is enforced in Objective-C in ways that are often best practices in other languages.
Declared properties, which are discussed in the next section, shows you how this is done in Objective C. This section also explains why, at first glance, it can appear that you can access internal data from another object and why, at second glance, you will see that it is only the appearance of direct access.