协议与类别
任何人都可以解释Objective-C中的协议和类别之间的区别吗? 你什么时候使用一个?
一个协议与Java中的一个接口是一样的:它本质上是一个契约,它说: “任何实现这个协议的类都将实现这些方法。
另一方面,类别只是将方法绑定到类。 例如,在Cocoa中 ,我可以为NSObject
创build一个类别,允许我将方法添加到NSObject
类(当然还有所有的子类), 即使我没有真正的访问NSObject
。
总而言之:协议规定了一个类将要实现的方法; 一个类别将方法添加到现有的类。
每一个的正确使用应该是明确的: 使用协议来声明一个类必须实现的方法集合,并使用类别来添加方法到现有的类。
一个协议说,“这里有一些方法,我希望你执行。” 一个类别说:“我用这些额外的方法扩展了这个类的function”。
现在,我怀疑你的困惑源于苹果使用“非正式协议”这个短语。 这是关键(也是最令人困惑的):非正式协议实际上并不是协议。 它实际上是NSObject的一个类别。 cocoa使用非正式的协议来为代表提供接口。 由于@protocol
语法在Objective-C 2.0之前不允许使用可选方法,所以Apple实现了可选方法,无需执行任何操作(或返回一个虚拟值)以及所需的方法来引发exception。 没有办法通过编译器强制执行此操作。
现在,在Objective-C 2.0中, @protocol
语法支持@optional
关键字,将协议中的某些方法标记为可选。 因此,只要它实现了所有标记为@required
的方法,你的类就符合协议。 编译器可以确定你的类是否实现了所有必需的方法,这是一个巨大的节省时间。 iPhone SDK独占地使用了Objective-C 2.0 @protocol
语法,我想不出有什么好的理由不要在任何新的开发中使用它(除了需要在早期版本的Mac OS上运行的Mac OS X Cocoa应用程序X)。
分类:
类别是向现有类的所有实例添加新方法而不修改类本身的一种方法。
如果您希望将function添加到现有类而不从该类派生或重写原始类,则可以使用类别。
假设您在cocoa中使用NSView
对象,并且您发现自己希望NSView
所有实例都能够执行某些操作。 显然,你不能重写NSView
类,即使你从它派生出来,并不是你的程序中的所有NSView
对象都是你的派生types。 解决方法是在NSView
上创build一个类别,然后在程序中使用它。 只要你#import
包含你的类别声明的头文件,它就会出现,好像每个 NSView
对象都响应你在类别源文件中定义的方法。
协议:
协议是任何类可以select实现的方法的集合。
当你想提供一个保证,某个类将响应一组特定的方法时,你使用一个协议。 当一个类采用协议时,它承诺实现在协议头中声明的所有方法。 这意味着任何其他使用该类的类都可以确定这些方法将被执行,而无需了解该类。
当创build一个类似的类的家庭,这一切都需要与一个共同的“控制器”类进行通信。 控制器类和受控类之间的通信都可以打包成一个单一的协议。
注意:Objective-C语言不支持多重inheritance(一个类只能从一个超类派生),但是许多相同的function可以由协议提供,因为一个类可以符合几种不同的协议。
据我了解,协议有点像Java的接口。 协议声明方法,但是实现取决于每个类。 分类看起来像Ruby的mixin。 使用类别,您可以将方法添加到现有的类。 即使是内置的类。
一个协议允许你声明一个不限于任何特定的类或类别的方法列表。 协议中声明的方法可以采用任何类别/类别。 采用协议的类或类必须实现协议中声明的所有必需的方法。
一个类别允许你添加额外的方法到现有的类,但是他们不允许额外的实例variables。 类别添加的方法成为类types的一部分。
协议是实现指定方法的契约。 任何符合协议的对象都同意为这些方法提供实现。 协议的一个很好的用法是为一个委托定义一组callback方法(委托人必须响应所有的方法)。
类别提供了通过向其添加方法(类或实例方法)来扩展当前对象的function。 一个很好的用法是扩展NSString类来添加之前没有的function,例如添加一个方法来创build一个将接收器转换为1337 5P34K的新string。
NSString *test = @"Leet speak"; NSString *leet = [test stringByConvertingToLeet];
来自SGKochan的“Objective-C编程”定义
分类:
类别为您提供了一种简单的方法,将类的定义模块化为相关方法的组或类别。 它还为您提供了一种简单的方法来扩展现有的类定义,甚至无需访问类的原始源代码,也无需创build子类。
协议:
协议是在类之间共享的方法列表。 协议中列出的方法没有相应的实现; 他们的意思是由其他人(如你)来实施。 协议提供了一种方法来定义一组与特定名称相关的方法。 通常将这些方法logging下来,以便您知道它们如何执行,以便您可以根据需要在自己的类定义中实现它们。 协议列出了一组方法,其中一些方法可以select实现,另一些方法则需要实现。 如果您决定为特定协议实施所有必需的方法,则说您遵守或采用了该协议。 您可以定义一个协议,其中所有方法都是可选的,或者是所有方法都是必需的。