Understanding inheritance in Portfolio.h


#1

Hi,

I’ve managed to get the challenge to work, but I could do with some help understanding how inheritance works here.

Originally, I had the following set up: the Portfolio class provides a single array “portfolio” which was populated by one of two methods “addStocks:(StockHolding *)” or “addForeignStocks:(ForeignStockHolding *)”. This worked fine.

My reasons for having two methods was that I assume you’d want to know whether that element of the array had the extra information (conversionRate) or not. (I’m now not sure that’s valid, because I presume you’d handle the difference in another part of the code, but that was the original reasoning…)

Then I tried having a single method: I imported StockHolding.h into Portfolio.m and had the single method addStocks:(StockHolding *) and this worked fine. The results were identical to having two methods.

Next, I tried importing only ForeignStockHolding.h and used the single method addStocks:(ForeignStockHolding *). The program ran and again gave identical results. However, this time I received ‘incompatible pointer type’ message when I called addStocks in main.m on objects of StockHolding class. I presume therefore that the correct way is to use the parent class in Portfolio.m, rather than the child. Is that because calling addStocks:StockHolding automatically includes any object of a child class?

That got me thinking: if you call the parent when it’s StockHolding, why don’t you go the whole hog and simply use addStocks:(NSObject *), as that’s the ‘ultimate’ parent? So I tried it, and it compiled and ran without any errors and produced precisely the same result as before.

Presumably there’s a downside to doing this, but I’m not sure I understand what it is…

Are there any general rules as to which is the best point in the inheritance chain to implement methods etc or have I totally misunderstood what’s going on…?


#2

In general, you want to give the compiler enough information to warn you if you’re trying to do something stupid, but you don’t want to specify something so far down in the hierarchy that valid objects won’t fit.

addStocks:(ForeignStockHolding *), as you noted, works but is incorrect, because not all holdings are foreign

addStocks:(NSObject *) is correct but less useful, because someone could try passing a string or any other object that isn’t relevant and won’t work at runtime (but the compiler won’t know better to complain)

addStocks:(StockHolding *) is correct and desirable

If you think about this not in terms of inheritance, but in terms of interface: you want to be able to pass any object that complies with the StockHolding definition, foreign or not, so that’s what you should use.


#3

Thanks for the quick reply – I’d sort of got there, but you’ve put it nice and concisely and it’s very helpful!

Regards

David