amazingjxq
amazingjxq

Reputation: 4677

How to reimplement property getter method in subclass?

I'm new to objective-c and found some OO features I have learned from other language is different in objective-c. The most confusing question for me until now is how to reimplement a property in subclass, or should I do this?

For example, I have two view controllers GameViewController and CardGameViewController.

@interface GameViewController : UIViewController {
    Game *_game;
}
@property (nonatomic) Game *game;
@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
@property (weak, nonatomic) IBOutlet UILabel *scoreLabel;
@property (weak, nonatomic) IBOutlet UILabel *messageLabel;
@end

@interface CardGameViewController : GameViewController
@property (nonatomic) CardMatchingGame *game;
@end

CardMatchingGame is derived from Game. @property game in GameViewController is implemented like below:

- (Game *)game
{
    if (!_game) {
        _game = [[Game alloc] initWithCardCount:[self.cardButtons count]
                                      usingDeck:[self createDeck]];
    }

    return _game;
}

I tried to reimplement @property game like below but got a warning in the return clause which said Incompatible pointer types returning 'Game *' from a function with result type 'CardMatchingGame *'.

- (CardMatchingGame *)game
{
    if (!_game) {

        _game = [[CardMatchingGame alloc] initWithCardCount:[self.cardButtons count]
                                                  usingDeck:[self createDeck]
                                             matchThreshold:self.threshold.selectedSegmentIndex + 2];
    }

    return _game;
}

Is this the correct way of reimplementing a property in subclass? If not, what am I supposed to do?

Upvotes: 0

Views: 82

Answers (3)

sage444
sage444

Reputation: 5684

I think the problem is ivar in parent class Game *_game; it produce warning you see. Try to use different name or id type for it.

or just cast it before return (CardMatchingGame *)_game;

Upvotes: 0

Mikkel Selsøe
Mikkel Selsøe

Reputation: 1201

If CardMatchingGame is a subclass of Game you can override - (Game *)game and return your CardMatchingGame object. Just make sure not to change the return type.

Upvotes: 0

Wain
Wain

Reputation: 119021

You can't reimplement like that (well, you could do a ton of casting, but that isn't a good option).

One option is to create the property as @property (nonatomic) id game; and then it can hold any type of Game class (or subclass) that you have. And, because it is id type the compiler will assume that any method you try to call is valid. Obviously you could make mistakes which you won't find till later.

Another, better, option is to add a new property in the subclass as @property (nonatomic) CardMatchingGame *cardGame; and, in the subclass, when a new game is created the CardMatchingGame instance is stored in both game and cardGame properties. Now, the superclass has access to game and can use it, and the subclass has access to cardGame, which is typed as the correct class. So, you have compiler checks and usage of the same instance in both classes. But, you haven't reimplemented a property - you have multiple properties, each doing the appropriate task for their location + purpose.

Upvotes: 2

Related Questions