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

时间:2009-06-13 09:07:46

标签: java objective-c

我认识Java,现在我正在学习Objective-C。 Java接口和Objective-C协议之间究竟有什么区别?

2 个答案:

答案 0 :(得分:81)

首先,来自Java创建者的一点historical perspective on the topic。接下来,维基百科有一个适度的帮助section on Objective-C protocols。特别要明白,Objective-C支持形式协议(使用@protocol关键字明确声明,相当于Java接口)和非正式协议 (只有一个或多个由类实现的方法,可以通过反射发现)。

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

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

注意:Apple的documentation州:

  

“此方法仅根据头文件中的正式声明来确定一致性,如上所示。它不会检查协议中声明的方法是否实际实现 - 这是程序员的责任。”

从Objective-C 2.0开始(在OS X 10.5“Leopard”和iOS中),正式协议现在可以定义可选方法,并且一个类符合协议,只要它实现所有所需方法。您可以使用@required(默认)和@optional关键字来切换是否必须必须 之后的方法声明才能符合协议。 (请参阅Apple Objective-C 2.0 Programming Language指南中讨论optional protocol methods的部分。)

可选的协议方法为开发人员提供了很大的灵活性,特别是用于实现代理侦听器。而不是扩展类似MouseInputAdapter(可能令人讨厌,因为Java也是单继承)或实现许多无意义的空方法,您可以采用协议并仅实现您关心的可选方法。使用此模式,调用者在调用之前检查该方法是否已实现(使用-respondsToSelector),如下所示:

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

如果反射的开销成为一个问题,你可以随时cache the boolean result for reuse,但要抵制过早优化的冲动。 : - )

答案 1 :(得分:18)

它们几乎相同。然而,有一件事让我感到震惊的是,除非你明确声明一个客观的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
相关问题