D. Fraction and Address Book Examples

Here, for your reference purposes, are the complete interface and implementation files for the fractions you worked with extensively in Part I, “The Objective-C Language,” and the address book example you worked with throughout Part II, “The Foundation Framework.” This includes the definitions for the Fraction, AddressCard, and AddressBook classes. You should implement these classes on your system. Also, extend the class definitions to make them more practical and powerful (for example, see exercises 2–7 at the end of Chapter 15, “Numbers, Strings, and Collections”). This is an excellent way for you to learn the language and become familiar with building programs, working with classes and objects, and (in the case of the address book) working with the Foundation framework.

The source code in this appendix (as with all the examples in this book) is also available from http://www.kochan-wood.com.

Recall that the Fraction class uses Object as its root object, whereas the AddressBook and AddressCard classes are Foundation classes and thus have NSObject as their roots.

The Fraction Class

Fraction Class Interface File

#import <objc/Object.h>

// Define the Fraction class

@interface Fraction : Object
{
  int  numerator;
  int  denominator;
}


-(Fraction *) initWith: (int) n: (int) d;

-(void) setNumerator: (int) n;
-(void) setDenominator:  (int) d;
-(void) setTo: (int) n over: (int) d;

-(int) numerator;
-(int) denominator;

-(void) reduce;
-(double) convertToNum;
-(void print;
@end

// Define the MathOps category

@interface Fraction (MathOps)
-(Fraction *) add: (Fraction *) f;
-(Fraction *) mul: (Fraction *) f;
-(Fraction *) sub: (Fraction *) f;
-(Fraction *) div: (Fraction *) f;
@end

Fraction Class Implementation File

#import "Fraction.h"
#import <stdio.h>

@implementation Fraction;

-(Fraction *) initWith: (int) n: (int) d
{
      self = [super init];
      if (self)
             [self setTo: n over: d];

      return self;
}

-(void) setNumerator: (int) n
{
      numerator = n;
}


-(void) setDenominator: (int) d
{
      denominator = d;
}

-(int) numerator
{
      return numerator;
}

-(int) denominator
{
      return denominator;
}

-(double) convertToNum
{
      if (denominator != 0)
             return (double) numerator / denominator;
      else
             return 0.0;
}

-(void) setTo: (int) n over: (int) d
{
      numerator = n;
      denominator = d;
}

- (void) reduce
{
      int  u = numerator;
      int  v = denominator;
      int  temp;

      if (u < 0)
            u = -u;

      while (v != 0) {
             temp = u % v;
             u = v;
             v = temp;
  }

      numerator /= u;
      denominator /= u;
}



-(void) print
{
      printf (" %i/%i ", numerator, denominator);
}
@end


// MathOps category implementation

@implementation Fraction (MathOps);
-(Fraction *) add: (Fraction *) f
{
      // To add two fractions:
      // a/b + c/d = ((a*d) + (b*c)) / (b * d)

      Fraction *result = [[Fraction alloc] init];
      int   resultNum, resultDenom;

      resultNum = (numerator * [f denominator]) +
        (denominator * [f numerator]);
      resultDenom = denominator * [f denominator];

      [result setTo: resultNum over: resultDenom];
      [result reduce];

      return result;
}

-(Fraction *) sub: (Fraction *) f
{
      // To sub two fractions:
      // a/b - c/d = ((a*d) - (b*c)) / (b * d)

      Fraction *result = [[Fraction alloc] init];
      int   resultNum, resultDenom;

      resultNum = (numerator * [f denominator]) -
        (denominator * [f numerator]);
      resultDenom = denominator * [f denominator];

      [result setTo: resultNum over: resultDenom];
      [result reduce];

      return result;
}


-(Fraction *) mul: (Fraction *) f
{
       Fraction *result = [[Fraction alloc] init];

       [result setTo: numerator * [f numerator]
            over: denominator * [f denominator]];
       [result reduce];

       return result;
}

-(Fraction *) div: (Fraction *) f
{
       Fraction *result = [[Fraction alloc] init];

       [result setTo: numerator * [f denominator]
            over: denominator * [f numerator]];
       [result reduce];

       return result;
}
@end

The AddressBook and AddressCard Classes

AddressCard Interface File

#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
#import <Foundation/NSArchiver.h>

@interface AddressCard: NSObject <NSCoding, NSCopying>
{
      NSString *name;
      NSString *email;
}

-(AddressCard *) initWithName: (NSString *) theName
                     andEmail: (NSString *) theEmail;

-(void) setName: (NSString *) theName;
-(void) setEmail: (NSString *) theEmail;
-(void) setName: (NSString *) theName andEmail: (NSString *) theEmail;
-(void) retainName: (NSString *) theName andEmail: (NSString *) theEmail;

-(NSString *) name;
-(NSString *) email;


-(NSComparisonResult) compareNames: (id) element;
-(void) print;
@end

AddressBook Interface File

#import <Foundation/NSArray.h>
#import "AddressCard.h"

@interface AddressBook: NSObject <NSCopying, NSCoding>
{
      NSString       *bookName;
      NSMutableArray *book;
}

-(id) initWithName: (NSString *) name;
-(void) setName: (NSString *) theName;
-(void) setBook: (NSArray *) theBook;

-(NSString *) bookName;
-(NSMutableArray *) book;

-(void) addCard: (AddressCard *) theCard;
-(void) removeCard: (AddressCard *) theCard;

-(AddressCard *) lookup: (NSString *) theName;

-(int) entries;
-(void) list;
-(void) sort;

@end

AddressCard Implementation File

#import "AddressCard.h"

@implementation AddressCard;

-(id) initWithName: (NSString *) theName andEmail: (NSString *) theEmail
{
  self = [super init];

  [self setName: theName andEmail: theEmail];
  return self;
}

-(void) setName: (NSString *) theName
{
  [name autorelease];
  name = [theName copy];
}

-(void) setEmail: (NSString *) theEmail
{
  [email autorelease];
  email = [theEmail copy];
}

-(void) setName: (NSString *) theName andEmail: (NSString *) theEmail
{
  [self setName: theName];
  [self setEmail: theEmail];
}

-(NSString *) name
{
  return name;
}

-(NSString *) email
{
  return email;
}

-(NSComparisonResult) compareNames: (id) element
{
  return [name compare: [element name]];
}
-(void) dealloc
{
  [name release];
  [email release];
  [super dealloc];
}


-(void) print
{
printf ("==================================== ");
printf ("| |                                  ");
printf ("| %-31s |                            ", [name cString]);
printf ("| %-31s |                            ", [email cString]);
printf ("| |                                  ");
printf ("| |                                  ");
printf ("| |                                  ");
printf ("|            O O |                   ");
printf ("==================================== ");
}

-(void) encodeWithCoder: (NSCoder *) encoder
{
   if ( [encoder allowsKeyedCoding] ) {
      [encoder encodeObject: name forKey: @"AddressBookname"];
      [encoder encodeObject: email forKey: @"AddressBookemail"];
   } else {
      [encoder encodeObject: name];
      [encoder encodeObject: email];
   }
}

-(id) initWithCoder: (NSCoder *) decoder
{
   if ( [decoder allowsKeyedCoding] ) {
      name = [[decoder decodeObjectForKey: @"AddressBookname"] retain];
      email = [[decoder decodeObjectForKey: @"AddressBookemail"] retain];
   } else {
      name = [[decoder decodeObject] retain];
      email = [[decoder decodeObject] retain];
}

      return self;
}

-(AddressCard *) copyWithZone: (NSZone *) zone
{
  AddressCard *newCard = [[AddressCard allocWithZone: zone] init];

  [newCard retainName: name andEmail: email];
  return newCard;
}

-(void) retainName: (NSString *) theName andEmail: (NSString *) theEmail
{
  name = [theName retain];
  email = [theEmail retain];
}
@end

AddressBook Implementation File

#import "AddressBook.h"

@implementation AddressBook;

// set up the AddressBook's name and to an empty book

-(id) initWithName: (NSString *) name
{
  self = [super init];
  if (self != nil) {
  bookName = [name copy];
    book = [[NSMutableArray alloc] init];
    // cleanup if the book doesn't initialize
      if (book == nil) {
      [self autorelease];
  self = nil;
  }
  }
  return self;
}
-(void) setName: (NSString *) theName
{
  [bookName autorelease];

  bookName = [theName copy];
}

-(void) setBook: (NSArray *) theBook
{

[book autorelease];
  book = [[NSMutableArray alloc] initWithArray: theBook];
}

-(void) addCard: (AddressCard *) theCard
{
  [book addObject: theCard];
}

-(NSMutableArray *) book
{
  return [book [mutableCopy autorelease]];
}

-(NSString *) bookName
{
  return [bookName [mutableCopy autorelease]];
}


-(void) removeCard: (AddressCard *) theCard
{
  [book removeObjectIdenticalTo: theCard];
}

-(void) sort
{
[book sortUsingSelector: @selector(compareNames:)];
}


// lookup address card by name – returns 1st exact match

-(AddressCard *) lookup: (NSString *) theName
{
  AddressCard *nextCard;

  int  i, elements;

  elements = [book count];

  for ( i = 0; i < elements; ++i) {
    nextCard = [book objectAtIndex: i];

    if ( [[nextCard name] caseInsensitiveCompare: theName]
         == NSOrderedSame )
      return nextCard;
  }

  return nil;
}
  -(int) entries
{
  return [book count];
}

-(void) list
{
  int   i;
  AddressCard *theCard;

int   elements = [book count];

  printf (" ======== Contents of: %s ========= ", [bookName cString]);
  for ( i = 0; i < elements; ++i ) {
     theCard = [book objectAtIndex: i];
     printf ("%-20s %-32s ", [[theCard name] cString],
        [[theCard email] cString]);
  }

  printf ("==================================================== ");
}

-(void) dealloc
{
  [bookName release];
  [book release];
  [super dealloc];
}

// Methods for NSCoding protocol

-(void) encodeWithCoder: (NSCoder *) encoder
{
  if ( [encoder allowsKeyedCoding] ) {
    [encoder encodeObject:bookName forKey: @"AddressBook bookName"];
    [encoder encodeObject:book forKey: @"AddressBook book"];
  } else {
    [encoder encodeObject: bookName];
    [encoder encodeObject: book];
  }
}

-(id) initWithCoder: (NSCoder *) decoder
{
  if ( [decoder allowsKeyedCoding] ) {
     bookName = [[decoder decodeObjectForKey:
          @"AddressBook bookName"] retain];
     book = [[decoder decodeObjectForKey: @"AddressBook book"] retain];
  } else {
     bookName = [[decoder decodeObject] retain];
     book = [[decoder decodeObject] retain];
  }

  return self;
}


// Method for NSCopying protocol

-(AddressBook *) copyWithZone: (NSZone *) zone
{
  AddressBook *newBook = [[self class] allocWithZone: zone];

  [newBook initWithName: bookName];
  [newBook setBook: book];

  return newBook;
}
@end

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.37.123