如果您使用协议,那么您必须定义由两个类类型共享的方法两次。通常为特定模式(如委派模式)保留协议,以增加安全性并使您更难以犯错误,或者当已经嵌入类层次结构中的多个类需要共享常用方法并将此共享记录在某种方式。如果一个类可以表示为另一个类的更专业版本,则应该继承。
例如,假设你在游戏中有一个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