2013-02-14 187 views
5

In objective-c?使用Protocol vs Inheritance的优点和缺点是什么?

我有一门课,然后我决定要另一门课,就像第一节课。我应该使用协议,并确保两个类都支持该协议,或者我应该创建一个父类,并决定这两个类是从哪一个类继承的?

注:

的类别是:企业,产品目录,AddressAnnotation(目前仅仅适用于业务)和AddressAnnotationView(目前仅在唯一的业务)。我想在Catalog上使用同样的东西。还有BGGoogleMapCacheForAllAnnotations,当注释聚集在一起时(它们现在应该能够处理CatalogAnnotation for Catalog和Business),还有BGGoogleMap View Controller,我想把它变成父类。

+0

第一堂课是什么,第二堂课是什么?他们有多少共同点?如果它询问了一个或多个特定场景,这个问题会更好。没有投票结束,但指出这个问题有点太广泛而不容易回答。 – paulmelnikow 2013-02-14 05:45:06

回答

7

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

例如,假设你在游戏中有一个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,我会在我的代理上调用此方法时收到警告,因为它的实现无法找到,而如果我导入委托的头/静态键入委托,类不再被封装。

在大多数情况下,您在技术上不需要协议;你可以在所有通常遵守上述协议的类中定义所有没有协议的方法,并且一切都可以正常工作。但是,这些常用方法不再有记录。因此,除了知道某些类或匿名对象实现您需要它们实现的方法的安全性之外,您还可以快速知道什么是什么以及如何做。 当您需要确保某个类或某个类的实例实现某种方法时,特别是在不应该知道对象的类型以保持类封装的情况下,协议适用于该类。

+0

这是一个更好的答案。 – 2013-02-14 04:39:43

+0

@JimThio谢谢。我花了一段时间。 – Metabble 2013-02-14 04:41:05

+0

另一件需要考虑的协议是谁将会使用你的代码。作为开发自己项目的个人开发人员,设置协议的选择主要取决于您自己的工作流程和偏好。如果您在一个团队工作,或者您打算稍后将您的项目交给其他人,那么它可能是一个有价值的组织工具,可以帮助其他开发人员处理您的代码。 – 2013-02-14 04:49:25

3

有一个很多因素可能会影响这个决定,例如,当你说其他班级“像第一班”时,这意味着什么呢?这是否意味着他们将完全相同的90%这是否意味着他们会做很多相同的事情,但每种都会以一种稍微不同的方式进行呢?

如果第一个类中的许多现有方法将按原样或稍作修改在第二类中,子类化可以让你获得所有这些方法“免费”,所以你可以专注于差异。但是,如果您需要重写大部分代码,并且只想将这两个类定义为执行类似的操作,那么协议可能更有意义。

我个人完全使用子类化,主要是因为我没有遇到一种情况,在我的代码中,一个协议对我来说是有意义的 - 当然,过了一段时间,它比习惯决定更习惯于习惯。当我开始将我的应用程序转换为使用Core Data时,子类化非常好,因为Core Data提供了创建具有继承属性和关系的子实例的功能。这使得概念上更容易掌握。如果你考虑你当前的代码,你已经是子类化(NSObject,视图控制器等),并可能使用协议(NSCoding,查看委托等)。考虑你如何使用这些现有的类和协议,以及这些用例如何应用于你自己的类。

+0

这很容易理解。恰好解释道。 – viral 2013-02-14 05:21:43

相关问题