It looks like a bit of a flaw in the object model, so perhaps you should return PlayingCards
, but if you need to do this, the safe way is to check the Class of the object, and then cast it and make the method calls.
if ([card isKindOfClass: [PlayingCard class]]) {
[(PlayingCard*)card doMyPlayingCardMethod];
}
This safely checks that the card
object is a PlayingCard
or a derivative, and then calls the -doMyPlayingCardMethod
method on it.
As far as the "what's the point of subclassing?" question, it's really more for the other case. So, for example, if you had FacePlayingCard
and NumberPlayingCard
that were all subclasses of PlayingCard
, you could have a -drawCard
method that knew how to draw the face cards differently than the number cards.
In this case, you're abstracting Card
from PlayingCard
, but there doesn't seem to be anything you want to do with Card
, so it's kind of a meaningless place to put the subclass.
If, on the other hand, you had CollectingCard
which was also a subclass of Card
and you wanted to be able to shuffle them as well, that would make some more sense.