[ Team LiB ] |
1.3 ClassesObjects in Objective-C are defined in terms of a class. New classes of objects are specializations of a more general class. Each new class is the accumulation of the class definitions that it inherits from and can expand on that definition by adding new methods and instance variables or redefining existing methods to perform new or expanded functionality. Like Java and Smalltalk, but unlike C++, Objective-C is a single inheritance language, meaning that a class can inherit functionality only from a single class. A class is not just a blueprint for building objects; it is itself an object in the runtime that knows how to build new objects. These new objects are instances of the class. 1.3.1 The Root ClassEvery class hierarchy begins with a root class that has no superclass. While it is possible to define your own root class in Objective-C, the classes you define should inherit, directly or indirectly, from the NSObject class provided by the Foundation framework. The NSObject class defines the behavior required for an object to be used by the Cocoa framework and provides the following functionality:
1.3.2 Defining a ClassIn Objective-C, classes are defined in two parts, usually separated into two different files:
1.3.2.1 The interfaceTo declare a class and give all the information other classes (and other programs) need to use it, an interface file needs to contain the following information:
Example 1-1 shows simple header file, saved by convention as Song.h, containing the interface for the Song class. Example 1-1. A simple header file for the Song class#import <Cocoa/Cocoa.h> // 1 @interface Song : NSObject { // 2 id title; // 3 } - (id)title; // 4 - (void)setTitle:(id)aTitle; // 5 @end; // 6 Each line is defined as follows:
1.3.2.2 Scoping instance variablesThe object-oriented principle of encapsulation means that other programmers shouldn't need to know a class's instance variables. Instead, they need to know only the messages that can be sent to a class. The inclusion of instance variables in the interface file, while required by C, would seem to break encapsulation. To give a class the ability to enforce encapsulation even though the variables are declared in the header file, the compiler limits the scope of the class's instance variables to the class that declares them and its subclasses. This enforcement can be changed by using the following set of compiler directives:
For example, to ensure that subclasses of the Song class could not directly access the title instance variable, use the @private directive as shown in Example 1-2. Example 1-2. Constraining a variable's scope#import <Cocoa/Cocoa.h> @interface Song : NSObject { @private id title; } - (id)title; - (void)setTitle:(id)aTitle; @end; 1.3.2.3 The implementationTo define how the class works, an implementation file needs to contain implementations of the methods defined in the interface file. Example 1-3 shows the implementation, contained in the source file Song.m by convention, of the Song class. Example 1-3. Implementation of the Song class#import Song.h // 1 @implementation Song // 2 - (id)title { // 3 return title; } - (void)setTitle:(id)aTitle { // 4 [title autorelease]; title = [aTitle retain]; } @end // 5 Here is a detailed explanation of each part of this code:
Notice that the implementation doesn't need to repeat the superclass name or the instance variable declarations. 1.3.3 Special VariablesIn addition to a class's instance variables, several other instance variables are defined within the scope of instance methods. These variables are:
1.3.4 Class MethodsSince classes are objects, you can define methods that will act when messages are sent to a class. Class methods are defined in the same way as instance methods, except you use a plus symbol (+) at the beginning of the method declaration instead of a hyphen or minus sign (-). For example, if the Song class keeps track of the number of songs created, a numberOfSongs class method could be provided, as shown in Example 1-4. Example 1-4. Defining a class method#import <Cocoa/Cocoa.h> @interface Song : NSObject { id title; } + (int)numberOfSongs; - (id)title; - (void)setTitle:(id)aTitle; @end; Similarly, this method's implementation is placed between the @implementation and @end directives in the implementation (.m) file. Since a class method operates on the class object, the isa, self, super, and _cmd variables are defined the same way as instance variables.
1.3.5 Overriding Superclass MethodsWhen a new class is defined, a method can be implemented with the same name as a method in one of the superclasses up the inheritance hierarchy. This new method overrides the original when messages with the method name are sent to the derived class's object. When overriding methods, you can access the superclass's method functionality by sending a message to the special variable super. For example, if the class of iPod inherits from a more generic MP3Player class that also defines the play method, the subclass's play method may require that the superclass functionality is executed. Example 1-5 shows how this could be achieved by using the super variable. Example 1-5. Overriding a superclass method- (void)play { [self setPlayIndicator:YES]; [super play]; } When a superclass method is overridden, the method doesn't need to be declared again in the interface (.h) file. By convention, an overridden method is listed in the interface file only if you significantly change the way the method works.
|
[ Team LiB ] |