Cocoa Programming for Mac OS X - Aaron Hillegass [19]
It is important to keep track of the difference between “uses” and “is a subclass of.” The beginner would say, “BankAccount inherits from NSMutableArray.” The old hand would say, “BankAccount uses NSMutableArray.” In the common idioms of Objective-C, “uses” is much more common than “is a subclass of.”
You will find it much easier to use a class than to subclass one. Subclassing involves more code and requires a deeper understanding of the superclass. By using composition instead of inheritance, Cocoa developers can take advantage of very powerful classes without really understanding how they work.
In a strongly typed language, such as C++, inheritance is crucial. In an untyped language, such as Objective-C, inheritance is just a hack that saves the developer some typing. There are only two inheritance diagrams in this entire book. All the other diagrams are object diagrams that indicate which objects know about which other objects. This is much more important information to a Cocoa programmer.
Creating Your Own Classes
Where I live, the state government has decided that the uneducated have entirely too much money: You can play the lottery every week. Let’s imagine that a lottery entry has two numbers between 1 and 100, inclusive. You will write a program that will make up lottery entries for the next ten weeks. Each LotteryEntry object will have a date and two random integers (Figure 3.5). Besides learning how to create classes, you will build a tool that will certainly make you fabulously wealthy.
Figure 3.5. Completed Program
Creating the LotteryEntry Class
In Xcode, create a new file. Select Objective-C class as the type. Name the class LotteryEntry, and set it to be a subclass of NSObject (Figure 3.6).
Figure 3.6. New LotteryEntry Class
Note that you are also causing LotteryEntry.h to be created. Drag both files into the lottery group if they are not already there.
LotteryEntry.h
Edit the LotteryEntry.h file to look like this:
#import @interface LotteryEntry : NSObject { NSDate *entryDate; int firstNumber; int secondNumber; } - (void)prepareRandomNumbers; - (void)setEntryDate:(NSDate *)date; - (NSDate *)entryDate; - (int)firstNumber; - (int)secondNumber; @end You have created a header file for a new class called LotteryEntry that inherits from NSObject. It has three instance variables: • entryDate is an NSDate. • firstNumber and secondNumber are both ints. You have declared five methods in the new class: • prepareRandomNumbers will set firstNumber and secondNumber to random values between 1 and 100. It takes no arguments and returns nothing. • entryDate and setEntryDate: will allow other objects to read and set the variable entryDate. The method entryDate will return the value stored in the entryDate variable. The method setEntryDate: will allow the value of the entryDate variable to be set. Methods that allow variables to be read and set are called accessor methods. • You have also declared accessor methods for reading firstNumber and secondNumber. (You have not declared accessors for setting these variables; you are going to set them directly in prepareRandomNumbers.) LotteryEntry.m Edit LotteryEntry.m to look like this: #import "LotteryEntry.h" @implementation LotteryEntry - (void)prepareRandomNumbers { firstNumber = ((int)random() % 100) + 1; secondNumber = ((int)random() % 100) + 1; } - (void)setEntryDate:(NSDate