Amazon.com Widgets Exercise 2
Welcome, Guest. Please login or register.
Did you miss your activation email?
April 20, 2014, 03:48:36 AM
Home Help Search chat Login Register 
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan
                     

+ Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+ Old Stuff
| |-+ Answers to Exercises
| | |-+ Chapter 10
| | | |-+ Exercise 2
Pages: [1] Go Down
Print
Author Topic: Exercise 2 (Read 2841 times)
adamgonzalez1984
Jr. Member
**
Posts: 89






on: February 23, 2009, 12:32:35 PM

Here's what I got for exercise 2....

Square.h
#import <Foundation/Foundation.h>


@interface Square : NSObject

{
   int side;
}

@property int side;


-(void) setSide: (int) s;
-(Square *) initWithSide: (int) s;
-(void) print;



@end


Square.m
#import "Square.h"


@implementation Square
@synthesize side;

-(void) setSide: (int) s
{
   side = s;
}
-(Square *) initWithSide: (int) s
{
   self = [super init];
   
   if (self)
      [self setSide:s];
   
   return self;
}
-(void) print
{
   NSLog(@"\nMy Square Side = %i", side);
}


@end



main.m
#import "Rectangle.h"
#import "Square.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   Rectangle *myRect;
   Square *mySquare;
   
   myRect = [[Rectangle alloc] initWithWidth: 15 andHeight: 18];   
   mySquare = [[Square alloc] initWithSide:15];
   
   
   myRect.print;
   mySquare.print;
   

   [myRect release];
   [mySquare release];

    [pool drain];
    return 0;
}

Comments, Questions, Corrections, Improvements etc ..  are always welcome
Logged
mdeh
Full Member
***
Posts: 166






Reply #1 on: February 23, 2009, 05:54:06 PM

Here's what I got for exercise 2....

Square.h
#import <Foundation/Foundation.h>


@interface Square : NSObject

I think what Steve is after here is the fact that square is a subclass of Rectangle, so I think the interface should read
Code: (Objective-C)
@interface Square : Rectangle

Quote

-(Square *) initWithSide: (int) s
{
   self = [super init];
   
   if (self)
      [self setSide:s];
   
   return self;
}



You should use the designated initializer of the rectangle class...well, that's what the exercise calls for.

So,
Code: (Objective-C)
-(Square *) initWithSide: (int) s
{
self = [initWithWidth: s andHeight: s];

if (self)
  return self;
}

or simply

Code: (Objective-C)
-(Square *) initWithSide: (int) s
{
return [self initWithWidth: side andHeight: side];
}

I think!  :-)
Last Edit: February 23, 2009, 05:58:48 PM by mdeh Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #2 on: March 09, 2009, 07:33:24 AM

A comment:


@property int side;


-(void) setSide: (int) s;
   ...

You don't need to supply a setSide: method since you are synthesizing it.


Cheers,

Steve
Last Edit: March 18, 2009, 07:09:11 PM by skochan Logged
adamgonzalez1984
Jr. Member
**
Posts: 89






Reply #3 on: April 27, 2009, 12:43:11 PM

Hello all,

    I got stuck half way through the book and decided to go back to the beginning and here I am back at chapter 10.

  I got exercise 2 to work and I get the result that I want but I am still getting this warning:

"warning: assignment from distinct Objective-C type"

Here's my code:

Square.h

Quote
#import "Rectangle.h"

@interface Square : Rectangle


-(int) side;
-(Square *) initWithSide: (int) side;
@end

Square.m

Quote
#import "Square.h"


@implementation Square



-(int) side
{
   return width;
}
-(Square *) initWithSide: (int) side
{
   self = [super initWithWidth: side andHeight: side];
   
   if (self)
      return self;
}
@end

Chapter10E2.m

Quote
#import "Square.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   Square *mySquare = [[Square alloc] initWithSide:3];
   
   NSLog(@"%i", [mySquare side]);
       
   [mySquare release];

   
   
    [pool drain];
    return 0;
}

What is going wrong?
Last Edit: April 27, 2009, 12:45:23 PM by adamgonzalez1984 Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #4 on: April 27, 2009, 01:12:24 PM

So I'm not sure where I mentioned this in the book, but the Rectangle's initWithWidth:andHeight: method should be declared to return type id not Rectangle *

It's just for these type of cases, either where super is called (as you are doing) or an inherited method is used (through subclassing)  that you want the method to return a generic object pointer (type id) as opposed to a distinct class.

In your case, the warning comes from here:

Code: (Objective-C)
self = [super initWithWidth: side andHeight: side];

since self is a Square object and the init routine returns a Rectangle.


Hope that makes sense!

Cheers,

Steve
Last Edit: April 27, 2009, 03:12:55 PM by skochan Logged
adamgonzalez1984
Jr. Member
**
Posts: 89






Reply #5 on: April 27, 2009, 01:42:33 PM

Makes perfect sense now.  Thanks a bunch!!!!
Logged
strells
Newbie
*
Posts: 8






Reply #6 on: May 12, 2009, 06:50:48 PM

So I'm not sure where I mentioned this in the book, but the Rectangle's initWithWidth:andHeight: method should be declared to return type id not Rectangle *

It's just for these type of cases, either where super is called (as you are doing) or an inherited method is used (through subclassing)  that you want the method to return a generic object pointer (type id) as opposed to a distinct class.

In your case, the warning comes from here:

Code: (Objective-C)
self = [super initWithWidth: side andHeight: side];

since self is a Square object and the init routine returns a Rectangle.


Hope that makes sense!

Cheers,

Steve

Now I'm really confused.  Doesn't exercise 2 say to use the method added in exercise 1 which does return Rectangle, not id?

Steve
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #7 on: May 12, 2009, 07:43:38 PM

Steve,

Yes, you're right.  I just realized now that I don't address the issue of returning an id type for an initializer until page 354 in the text.   Sad  I will have to address this earlier in a future printing/edition.

Thanks for pointing this out.

Cheers,

Steve Kochan
Last Edit: May 22, 2009, 02:43:44 PM by skochan Logged
markausitnberger
Newbie
*
Posts: 1


Email




Reply #8 on: May 22, 2009, 02:26:24 PM

Kochan,

I understand the reason for return to be of type id in this case and in others where the super class returns an object to a subclass trying to set a variable of it's own type to the super's return but which way is the best and why: 1) Set the super class's method to be return type id or 2) to type cast the return object from the super class to that of the subclass?

Thanks,
Berger
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #9 on: May 22, 2009, 02:49:28 PM

Number 1 is better, as id is used to represent a generic type.   If you declare your init routine to return an id type you're also indicating that the class might be subclassed; so that aids program readability.   In either case, you should typecast the result to the appropriate object type, and that again is a readability issue.

Cheers,

Steve
Logged
Pages: [1] Go Up
Print
Jump to:



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.