Java接口和Objective-C协议之间的区别?

我了解Java,现在我正在学习Objective-C。 Java接口和Objective-C协议究竟有什么不同?

首先,从Java的创造者之一, 就这个话题的一点历史观点 。 接下来,Wikipedia 对Objective-C协议有一个适度的帮助。 尤其要明白,Objective-C支持正式协议 (用@protocol关键字显式声明,等价于Java接口)和非正式协议 (只有一个或多个由类实现的方法,可以通过reflection)。

如果您采用正式协议(Objective-C术语“实现接口”),则编译器将发出未实现方法的警告,就像在Java中所期望的那样。 与Java(如skaffman所提到的)不同,如果一个Objective-C类实现了包含在正式协议中的方法,那么即使它的接口没有明确地采用它,也可以说它符合该协议。 您可以像这样在代码中testing协议一致性(使用-conformsToProtocol:) :

 if ([myObject conformsToProtocol:@protocol(MyProtocol)]) { ... } 

注意:Apple的文档指出:

“这种方法仅仅依据头文件中的正式声明来确定一致性,如上所述,它不检查协议中声明的方法是否被实际执行 – 这是程序员的责任。

从Objective-C 2.0开始(在OS X 10.5“Leopard”和iOS中),正式协议现在可以定义可选的方法 ,只要实现了所有必需的方法,类就符合协议。 您可以使用@required (默认)和@optional关键字来切换下面的方法声明是必须还是可能被实现以符合协议。 (请参阅Apple的Objective-C 2.0编程语言指南中讨论可选协议方法的部分 。)

可选的协议方法为开发人员提供了很大的灵活性,尤其是实现代理监听器 。 除了像MouseInputAdapter (这可能很烦人,因为Java也是单一的inheritance)或者实现了许多毫无意义的空方法之外,你可以采用一个协议,只实现你所关心的可选方法。 使用这种模式,调用者在调用它之前检查方法是否被实现(使用-respondsToSelector ),如下所示:

 if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) { [myObject fillArray:anArray withObject:foo]; ... } 

如果reflection的开销变成问题,则可以总是caching布尔结果以供重用 ,但是抵制过早优化的冲动。 🙂

他们几乎是相同的。 然而,有一件事让我意识到,除非你明确声明一个目标C协议也实现NSObject,否则对该协议的引用不能访问NSObject声明的方法(无论如何编译器警告)。 用java你可以有一个接口的引用,并仍然调用toString()等。

例如

目标C:

 @protocol MyProtocol // Protocol definition @end id <MyProtocol> myProtocol; [myProtocol retain] // Compiler warning 

Java的:

 public interface MyInterface { // interface definition } MyInterface myInterface; myInterface.toString(); // Works fine. 

目标C(固定):

 @protocol MyProtocol <NSObject> // Protocol definition @end id <MyProtocol> myProtocol; [myProtocol retain] // No Warning