My solution


#1

Question in the bottom vvv

ForeignStockHolding.h

[code]#import <Foundation/Foundation.h>
#import “StockHolding.h”

@interface ForeignStockHolding : StockHolding

@property float conversionRate;

@end[/code]

ForeignStockHolding.m

[code]#import “ForeignStockHolding.h”

@implementation ForeignStockHolding

@synthesize conversionRate;

  • (float)costInDollars
    {
    float convertedCost = [super costInDollars];
    return conversionRate * convertedCost;
    }

  • (float)valueInDollars
    {
    float convertedValue = [super valueInDollars];
    return conversionRate * convertedValue;
    }

@end
[/code]

main.m

[code]#import <Foundation/Foundation.h>
#import “ForeignStockHolding.h”

int main(int argc, const char * argv[])
{

@autoreleasepool {
    
    StockHolding *firstStock  = [[StockHolding alloc] init];
    StockHolding *secondStock = [[StockHolding alloc] init];
    ForeignStockHolding *thirdStock  = [[ForeignStockHolding alloc] init];
    
    [firstStock setPurchaseSharePrice:2.30];
    [firstStock setCurrentSharePrice:4.50];
    [firstStock setNumberOfShares:40];
    
    [secondStock setPurchaseSharePrice:12.19];
    [secondStock setCurrentSharePrice:10.56];
    [secondStock setNumberOfShares:90];
    
    [thirdStock setPurchaseSharePrice:2.30];
    [thirdStock setCurrentSharePrice:4.50];
    [thirdStock setNumberOfShares:40];
    [thirdStock setConversionRate:0.94];
    
    NSMutableArray *stocks = [[NSMutableArray alloc] initWithObjects:firstStock, secondStock, thirdStock, nil];
    
    for (StockHolding *s in stocks) {
        NSLog(@"Cost: %.2f. Value: %.2f.", [s costInDollars], [s valueInDollars]);
    }
    
    
}
return 0;

}[/code]

I actually didn’t think of using super for the challenge, but instead just did

Do you recommend I change my code if I see someone doing something smarter on the forum or just keep it as I wrote it first time?
By the way, would it be better to use

vs

?


#2

I’d use

By keeping it general, you can use any sort of StockHolding (Foreign or otherwise).

The less you can assume about an object that you are using, the better. When code changes (and it does), every assumption is a potential problem.


#3

Aaron,

Quick question based on what you said. I understand that we should have a pointer to Stockholdings instead of ForiegnStockHoldings in the for loop as it is more general (after all all ForiegnStockHolding objects are StockHoldings as well). However why does the loop execute properly if i write

[code]

for (ForiegnStockHolding *f in stocks){
NSLog(@"The Current Price is %.2f.\n The Share Numbers are %d.\n The Purchase Price is %.2f.\n The Total Cost in dollars is %.2f. \n The Total value in dollars is %.2f .\n ", [f currentPrice], [f shareNumbers], [f purchasePrice], [f costInDollars], [f valueInDollars]);

[/code

I mean the first two objects in the array are not ForiegnStockHoldings, they are StockHoldings and hence should not have properties of ForiegnStockHoldings. Yet the object created for the for loop seems to not care?


#4

You should try your loop and see what happens (making sure that StockHolding does not implement all of the methods implemented by the ForeignStockHolding.)

If you invoke a method on an object that doesn’t implement the method, you will get a runtime error.

//  main.m

#import <Foundation/Foundation.h>

@interface Bar: NSObject

@property int barness;

@end

@interface FooBar: Bar

@property int fooBarness;

@end

int main (int argc, const char * argv[])
{

    @autoreleasepool
    {
        Bar *b1 = [[Bar alloc] init];
        FooBar *fb1 = [[FooBar alloc] init];
        FooBar *fb2 = [[FooBar alloc] init];
        NSArray *bars = [NSArray arrayWithObjects:b1, fb1, fb2, nil];
        
        for (FooBar *fooBar in bars)
        {
            fooBar.fooBarness = 16;
        }
    }
    return 0;
}

@implementation Bar

@synthesize barness;

@end

@implementation FooBar

@synthesize fooBarness;

@end
2012-09-29 17:54:47.283 Inheritance[11600:403] -[Bar setFooBarness:]: unrecognized selector sent to instance 0x7fe279c140e0
2012-09-29 17:54:47.286 Inheritance[11600:403] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Bar setFooBarness:]: unrecognized selector sent to instance 0x7fe279c140e0'
*** First throw call stack:
(
	0   CoreFoundation                      0x00007fff929abf56 __exceptionPreprocess + 198
	1   libobjc.A.dylib                     0x00007fff8d717d5e objc_exception_throw + 43
	2   CoreFoundation                      0x00007fff92a381be -[NSObject doesNotRecognizeSelector:] + 190
	3   CoreFoundation                      0x00007fff92998e23 ___forwarding___ + 371
	4   CoreFoundation                      0x00007fff92998c38 _CF_forwarding_prep_0 + 232
	5   Inheritance                         0x0000000106aa4bd6 main + 566
	6   Inheritance                         0x0000000106aa4994 start + 52
	7   ???                                 0x0000000000000001 0x0 + 1
)
terminate called throwing an exception(lldb) 

Do not be afraid of experimenting in Xcode; you can not set off a nuclear reaction.


#5

Hmm, I tried doing that. In my case it seems to be executing properly.

Here is my code

StockHolding.h

#import <Foundation/Foundation.h>

@interface StockHolding : NSObject
{
    float purchaseSharePrice;
    float currentSharePrice;
    int numberOfShares;
    
}

-(float)purchasePrice;
-(float)currentPrice;
-(int)shareNumbers;

-(void)setPurchasePrice:(float)p;
-(void)setCurrentPrice:(float)c;
-(void)setShareNumbers:(int)s;

-(float)costInDollars;
-(float)valueInDollars;

@end

StockHolding.m


#import "StockHolding.h"

@implementation StockHolding

-(float)purchasePrice
{
    return purchaseSharePrice;
}

-(float)currentPrice
{
    return currentSharePrice;
    
}

-(int)shareNumbers
{
    return numberOfShares;
}

-(float)costInDollars
{
    return [self purchasePrice]*[self shareNumbers];
}

-(float)valueInDollars
{
    return [self currentPrice]*[self shareNumbers];
}

-(void)setPurchasePrice:(float)p
{
    purchaseSharePrice = p;
}

-(void) setShareNumbers:(int)s
{
    numberOfShares = s;
}

-(void)setCurrentPrice:(float)c
{
    currentSharePrice = c;
}

@end

ForiegnStockHolding.h

#import "StockHolding.h"

@interface ForiegnStockHolding : StockHolding

{
float conversionRate;
}


@property float conversionRate;

@end

ForiegnStockHolding.m

#import "ForiegnStockHolding.h"

@implementation ForiegnStockHolding


@synthesize conversionRate;

-(float) costInDollars
{
    return ([super costInDollars])*[self conversionRate];
}


-(float) valueInDollars
{
    return ([super valueInDollars])*[self conversionRate];
}

@end

main.h


#import <Foundation/Foundation.h>
#import "ForiegnStockHolding.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        StockHolding *apple = [[StockHolding alloc] init];
        [apple setCurrentPrice:687.56];
        [apple setShareNumbers:200];
        [apple setPurchasePrice:680.76];
        
        StockHolding *google = [[StockHolding alloc] init];
        [google setCurrentPrice:700.56];
        [google setShareNumbers:500];
        [google setPurchasePrice:820.64];
        
        
        ForiegnStockHolding *fgoogle = [[ForiegnStockHolding alloc] init];
        [fgoogle setCurrentPrice:700.56];
        [fgoogle setShareNumbers: 500];
        [fgoogle setPurchasePrice:820.64];
        [fgoogle setConversionRate:.23];
        
        ForiegnStockHolding *fapple = [[ForiegnStockHolding alloc] init];
        [fapple setCurrentPrice:687.56];
        [fapple setShareNumbers:200];
        [fapple setPurchasePrice:680.76];
        [fapple setConversionRate:.23];
        
        
        //Add Objects to Array
        NSMutableArray *stocks = [NSMutableArray arrayWithObjects:apple,google,fapple,fgoogle, nil];
        
        //Iterate through Array
        for (ForiegnStockHolding *f in stocks){
        NSLog(@"The Stocks Held are %@", f);
            NSLog(@"The Current Price is %.2f.\n The Share Numbers are %d.\n The Purchase Price is %.2f.\n The Total Cost in dollars is %.2f. \n The Total value in dollars is %.2f .\n ", [f currentPrice], [f shareNumbers], [f purchasePrice], [f costInDollars], [f valueInDollars]);
            
            
        }
    }
    return 0;
}

As you can see that i have the same methods in StockHolding.m and ForiegnStockholding.m I am trying to make it so that it over rides the Stockholding.m method when a ForiegnStockHolding object is called and use the original super method when a Stockholding.m object is called. And if i compile this, this seems to be giving me the right answers (mathematically they add up) i just dont understand why its working for both.

Thank you again for helping me out ibex.