Зачем мне создавать свойство суперкласса только для использования подкласса

Я прохожу курс Стэнфордского онлайн-курса «Разработка приложений iOS 7 для iPhone и iPad» (ссылка на курс в itunes U).

В первом задании учащимся предлагается создать несколько классов (Card, PlayingCard, Deck, PlayingCardDeck), подробно описанных в примечаниях, и обновить контроллер представления для отображения случайной карты в колоде игральных карт.

Две обязательные задачи включают в себя:

  1. Добавьте частное свойство типа Deck * в CardGameViewController.
  2. Используйте отложенное создание экземпляров для выделения и инициализации этого свойства (в методе получения свойства), чтобы оно начиналось с полной колоды игральных карт.

Я добавил в свой код следующее:

// 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. Это совершенно законно в объектно-ориентированном программировании, потому что PlayingCardDeck наследуется от Deck и, таким образом, «является» Deck. Если вас смущает это понятие в объектно-ориентированном программировании, этот курс может показаться вам довольно сложным.

PlayingCardDeck является подклассом Deck. Я понимаю, что это "есть" колода.

Чего я не понимаю, так это почему свойство Deck используется вместо PlyaingCardDeck.


person Alex John    schedule 07.11.2013    source источник


Ответы (1)


Использование Deck в качестве типа свойства делает CardGameViewController более общим. Если вы захотите использовать другой тип колоды в будущем, вы можете просто изменить одну строку кода, в которой создается колода.

Кроме того, если вы просто сделаете это свойство общедоступным, вы сможете создавать разные CardGameViewController с разными типами колод вместо PlayingCardDeckGameViewController, TarotCardDeckGameViewController, PinochleCardDeckGameViewController и т. д.

В общем, использование Deck вместо PlayingCardDeck открывает для вас больше возможностей и увеличивает возможность повторного использования CardGameViewController.

person Jonathan Arbogast    schedule 07.11.2013
comment
Хотя я согласен с вашим объяснением, я думаю, что ОП также указывает на важный случай вероятного чрезмерного обобщения. Когда вы обобщаете частную собственность на случай, если когда-нибудь сделаете ее общедоступной, вы, вероятно, перепроектировали систему и должны упрощать до тех пор, пока вам не понадобится этот уровень абстракции. - person Rob Napier; 07.11.2013
comment
Спасибо, это то объяснение, которое я искал, но не нашел. @Rob Napier, скорее всего, ты прав. Это первое задание, и я ожидаю, что этот проект будет развиваться. Собственность может быть частной по причине, которая станет более ясной позже. - person Alex John; 07.11.2013
comment
Это отличный момент @RobNapier. В этом конкретном классе Пол Хегарти устанавливает такие вещи, потому что, я думаю, на другом уроке или задании он предлагает ученикам использовать другие виды колод. Так что это странная ситуация, когда Пол руководит дизайном и знает, куда он идет, но не делится всей этой информацией со студентами сразу. - person Jonathan Arbogast; 07.11.2013