为什么我只创建超类的属性才能使用子类

时间:2013-11-07 19:23:11

标签: objective-c oop inheritance typing declared-property

我正在关注斯坦福在线课程开发适用于iPhone和iPad的iOS 7应用程序(link to course in itunes U)。

第一项作业要求学生在笔记中详细创建一些课程(卡片,PlayCard,Deck,PlayingCardDeck),并更新视图控制器以在一副扑克牌中显示随机卡片。

所需的两项任务包括:

  
      
  1. 将类型为Deck *的私有属性添加到CardGameViewController。
  2.   
  3. 使用延迟实例化来分配和初始化此属性(在属性的getter中)   所以它从一整套PlayCards开始。
  4.   

我在代码中添加了以下内容:

// CardGameViewController.m
#import "PlayingCardDeck.H"

@interface CardGameViewController ()
...
@property (strong, nonatomic) Deck *deck;
@end

@implementation CardGameViewController
- (Deck *)deck
{
    if (!_deck) _deck = [[PlayingCardDeck alloc] init];
    return _deck;
}
...
@end

提示表示以下内容:

  
      
  1. 即使您必须添加的属性类型必须是Deck(而不是PlayingCardDeck),您显然必须使用PlayingCardDeck懒惰地实例化它。这在面向对象编程中是完全合法的,因为PlayCardDeck继承自Deck,因此它“是一个”Deck。如果您对面向对象编程中的这个概念感到困惑,那么这个课程对您来说可能相当困难。
  2.   

PlayingCardDeck是Deck的子类。我知道它“是一个”甲板。

我不明白为什么使用Deck的属性代替PlyaingCardDeck。

1 个答案:

答案 0 :(得分:1)

使用Deck作为属性的类型可使您的CardGameViewController更通用。如果您希望将来使用不同类型的套牌,您只需更改创建套牌的一行代码即可。

此外,如果您只是公开该属性,则可以使用不同类型的套牌创建不同的CardGameViewController,而不是PlayingCardDeckGameViewControllerTarotCardDeckGameViewController以及{{1等等。

通常,使用PinochleCardDeckGameViewController代替Deck可以为您打开更多选项,并提高PlayingCardDeck的可重用性。