如果您使用協議,那麼您必須定義由兩個類類型共享的方法兩次。通常爲特定模式(如委派模式)保留協議,以增加安全性並使您更難以犯錯誤,或者當已經嵌入類層次結構中的多個類需要共享常用方法並將此共享記錄在某種方式。如果一個類可以表示爲另一個類的更專業版本,則應該繼承。
例如,假設你在遊戲中有一個Vehicle
類,它知道如何做各種各樣的東西,比如四處走動。如果你想創建一個Car
類,你可能繼承了這個類,這樣你就可以繼承它的所有方法實現;無論是批量使用它們還是實現你自己的方法版本,在調用超類的實現之前,可能還要執行一些特定於子類的任務。 當您想要以某種方式修改超類的特性和行爲時,子類化可用於此目的。當額外的數據必須添加到類中時,尤其如此,例如實例變量,因爲您無法使用類別(儘管您可以使用Class Extension
,通常被認爲是一種私有界面)。一般而言,子類的結果是超類。
協議就是這樣,協議。他們在那裏防止你搞砸或忘記某些東西,並確保每個對象都做它應該做的事情,當類沒有像他們應該做的那樣行事時觸發編譯器警告。這對於委託等模式很重要,因爲這是確保委託實現所需方法的唯一方法,除了破解封裝並知道代理的類型是什麼類型。例如,從我的一個項目中查看下面的代碼。
//SGSprite.h
@protocol SGSpriteDelegate
- (BOOL) animation:(int)animationIndex willCompleteFrameNumber:(int)frame forSprite:(id)sender;
@end
@interface SGSprite : NSObject
@property (nonatomic, assign) id<SGSpriteDelegate> delegate;
@end
//SGViewController.h
@interface SGViewController : UIViewController <SGSpriteDelegate>
//...dreadfully boring stuff
@end
許多類利用我的SGSprite
類渲染紋理二維四邊形。有時,他們需要知道精靈何時到達某個動畫幀,因此實例需要調用其代表的方法來讓他們知道何時到達某些幀。確保代理實現此類的唯一方法是實現此方法,並且實際上,如果有人試圖分配不作爲委託的對象,則通過使用協議來警告我。你會注意到,如果我只是簡單地讓委託爲一個普通的id
,我會在我的代理上調用此方法時收到警告,因爲它的實現無法找到,而如果我導入委託的頭/靜態鍵入委託,類不再被封裝。
在大多數情況下,您在技術上不需要協議;你可以在所有通常遵守上述協議的類中定義所有沒有協議的方法,並且一切都可以正常工作。但是,這些常用方法不再有記錄。因此,除了知道某些類或匿名對象實現您需要它們實現的方法的安全性之外,您還可以快速知道什麼是什麼以及如何做。 當您需要確保某個類或某個類的實例實現某種方法時,特別是在不應該知道對象的類型以保持類封裝的情況下,協議適用於該類。
第一堂課是什麼,第二堂課是什麼?他們有多少共同點?如果它詢問了一個或多個特定場景,這個問題會更好。沒有投票結束,但指出這個問題有點太廣泛而不容易回答。 – paulmelnikow 2013-02-14 05:45:06