5

在objective-c中?

我做了一堂课,然后我决定要另一堂课,就像第一堂课一样。我应该使用协议并确保两个类都支持该协议,还是应该创建一个父类并决定这两个类从那个类继承?

笔记:

这些类是:Business、Catalog、AddressAnnotation(目前仅适用于企业)和 AddressAnnotationView(目前仅适用于企业)。我希望在目录上也能做同样的事情。还有 BGGoogleMapCacheForAllAnnotations 管理注释何时聚集在一起(现在应该能够处理目录和业务的 AddressAnnotation。还有我想变成父类的 BGGoogleMap 视图控制器。

4

2 回答 2

8

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

例如,假设您Vehicle的游戏中有一个类知道如何做各种事情,例如四处走动。如果你想创建一个Car类,你可能会继承这个Vehicle类,这样你就可以继承它的所有方法实现;要么批发使用它们,要么实现你自己的方法版本,可能在调用超类的实现之前执行一些特定于子类的任务。子类化是为了当你想继承你的超类的特征和行为,同时以某种方式修改它。当必须将其他数据(例如实例变量)添加到类时尤其如此,因为您不能对类别执行此操作(尽管您可以使用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课程来渲染带纹理的 2D 四边形。有时,他们需要知道精灵何时到达动画的某个帧,因此SGSprite实例需要在其委托上调用一个方法来让他们知道何时到达某些帧。确保此类实例的委托实现此方法的唯一方法是使用协议,如果有人试图分配不作为委托的对象,确实会警告我。您会注意到,如果我简单地将委托设置为普通委托,那么id每当我在委托上调用此方法时都会收到警告,因为找不到它的实现,而如果我导入委托的标头/静态类型委托,则该类不再被很好地封装。

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

于 2013-02-14T04:37:07.593 回答
3

有很多因素会影响这个决定。一方面,当你说另一个班级“像头等舱”时,这是什么意思?这是否意味着他们会以完全相同的方式做 90% 的相同事情?这是否意味着他们会做很多相同类型的事情,但每件事的方式都略有不同?

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

我个人专门使用子类化,主要是因为我没有遇到协议在我的代码中对我有意义的情况——当然,一段时间后它更多的是出于习惯而不是有意识的决定。当我开始将我的应用程序转换为使用 Core Data 时,子类化非常适合,因为 Core Data 提供了创建具有继承属性和关系的子实体的能力。这使得从概念上更容易掌握。

如果您考虑当前的代码,您已经在子类化(NSObject、视图控制器等)并且可能使用协议(NSCoding、视图委托等)。想想你如何使用那些现有的类和协议,以及这些用例如何应用于你自己的类。

于 2013-02-14T04:33:06.213 回答