2013-08-22 211 views
0

我在這裏看到了很多有用的線索,但這是我第一次發佈!爲什麼我的超類對象調用其子類方法?

我正在參與臭名昭着的斯坦福開放課程項目:Matchismo。雖然我把所有事情都做好了,但我不明白示例代碼的一部分。

基本上下面的代碼是用來獲得一個卡對象與另一張卡進行比較。

- (void) flipCardAtIndex: (NSUInteger)index 
{ 
    Card *card = [self cardAtIndex:index]; 
    if (card && !card.isUnplayable) 
    { 
     if (!card.isFaceUp) 
     { 
      for (Card* otherCard in self.cards)//for-in loop 
      { 
       if (otherCard.isFaceUp && !otherCard.isUnplayable) 
       { 
        int matchScore = [card match:@[otherCard]]; 
...... 

這是cardAtIndex如何工作的:

-(Card *) cardAtIndex:(NSUInteger)index 
{ 
    if (index < [self.cards count]) 
     //dot notation is used for property 
     //[] is used for method 
    { 
     return self.cards[index]; 
    } 
    return nil; 
} 

下面是匹配(卡*)和Match(遊戲牌)

匹配(卡*)

-(int) match:(NSArray *)otherCards 
{ 
    NSLog(@"here"); 
    int score = 0; 

    for (Card *card in otherCards) 
    { 
     if ([card.content isEqualToString:self.content]) 
      score = 1; 
     { 
      NSLog(@"Card Match"); 
     } 

    } 
    return score; 
} 
方法

比賽(紙牌*)

-(int) match: (NSArray *)otherCards; 
{ 
    int score = 0; 
    if ([otherCards count] == 1) 
    { 
     PlayingCard *otherCard = [otherCards lastObject];//the last object in the array 
     if ([otherCard.suit isEqualToString:self.suit]) 
      score = 1; 
     else if (otherCard.rank == self.rank) 
      score = 4; 
     NSLog(@"PlayingCard Match"); 
    } 
    return score; 
} 

它工作得很好,但我不明白爲什麼當一個Card *對象調用一個方法時,它的子類的PlayingCard的方法被調用。 非常感謝您的幫助!

回答

1

這個概念被稱爲Polymorphism

它允許你有一個提供一些接口的基類,和一組以不同的方式實現這些方法的子類。典型示例是Drawable類方法draw及其子類CircleRectangle,它們都覆蓋draw方法以某種特定方式呈現其自身。

所以也適用於您的Card基類,它調用自己的接口方法match,但作爲一個對象其實不是的Card一個實例,但PlayingCard子類,子類方法被調用,而不是提供具體實施。

+0

感謝您的回答!我知道該實例應該是一個PlayingCard子類,但我不確定它是如何生成的。當我創建實例時,它是一個PlayingCard子類,但是當我調用一個方法將其作爲參數並返回一個Card類結果時,我不明白爲什麼它仍然是一個演示變量的實例變量方法 – Haoyu

+0

仔細查看在'cardAtIndex:'方法中,它不會創建一個Card實例,而是返回符合'Card'接口的東西,並且它的實現只返回一個'self.cards',每個都是'PlayingCard' 。爲什麼它不會被「鑄造」爲「卡片」類型?那麼在某些語言中它可以,但在Objective-C中,就像在許多動態類型語言中一樣,所有方法在默認情況下都是多態的。 (與C++相比,除非將其明確聲明爲'virtual',例如多態),否則轉換爲'Card'實際上會調用'Card'方法。 – iHunter

+0

很好的解釋。現在我明白了爲什麼。非常感謝! – Haoyu

0

在您的視圖控制器.m文件中,屬性「deck」必須初始化爲類PlayingCardDeck,而在PlayingCardDeck.m中,類的類別爲PalyingCard。因此,即使您將卡片宣佈爲班級卡片,它所調用的方法仍然是班級卡片中的一種。

相關問題