我是Objective-c的新手,发现我从其他语言中学到的一些OO功能在objective-c中是不同的。对我来说最令人困惑的问题是如何重新实现子类中的属性,还是应该这样做?
例如,我有两个视图控制器GameViewController
和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
源自Game
。 @property game
中的GameViewController
实现如下:
- (Game *)game
{
if (!_game) {
_game = [[Game alloc] initWithCardCount:[self.cardButtons count]
usingDeck:[self createDeck]];
}
return _game;
}
我尝试重新实现@property game
,如下所示,但在返回条款中发出了警告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;
}
这是在子类中重新实现属性的正确方法吗?如果没有,我该怎么办?
答案 0 :(得分:2)
你不能那样重新实现(好吧,你可以做大量的演员,但这不是一个好的选择)。
一个选项是将属性创建为@property (nonatomic) id game;
,然后它可以保存您拥有的任何类型的Game
类(或子类)。并且,因为它是id
类型,编译器将假定您尝试调用的任何方法都是有效的。很明显,你可能会犯错误,直到后来才能找到。
另一个更好的选择是在子类中添加一个新属性@property (nonatomic) CardMatchingGame *cardGame;
,并且在子类中,当创建新游戏时,CardMatchingGame
实例存储在game
中}和cardGame
属性。现在,超类可以访问game
并可以使用它,并且子类可以访问cardGame
,它被键入为正确的类。因此,您在两个类中都有编译器检查和相同实例的使用。但是,您还没有重新实现一个属性 - 您有多个属性,每个属性都针对其位置+目的执行相应的任务。
答案 1 :(得分:0)
如果CardMatchingGame
是Game
的子类,您可以覆盖- (Game *)game
并返回CardMatchingGame
个对象。只是确保不要更改返回类型。
答案 2 :(得分:0)
我认为问题是父类Game *_game;
中的ivar,它会产生你看到的警告。尝试使用不同的名称或id
类型。
或者只是在return (CardMatchingGame *)_game;