Java接口和Objective-C协议之间的区别?
我了解Java,现在我正在学习Objective-C。Java接口和Objective-C协议之间到底有什么区别?
我了解Java,现在我正在学习Objective-C。Java接口和Objective-C协议之间到底有什么区别?
首先,从Java的创建者之一的角度来谈谈这个话题的历史观点。接下来,维基百科有一个关于Objective-C协议的适度有用的部分。特别是,要了解Objective-C支持正式协议(使用关键字显式声明,相当于Java接口)和非正式协议(只是由类实现的一个或多个方法,可以通过反射发现)。@protocol
如果你采用一个正式的协议(Objective-C术语“实现接口”),编译器将发出未实现方法的警告,就像你在Java中期望的那样。与Java(如skaffman所提到的)不同,如果Objective-C类实现了正式协议中包含的方法,那么即使它的接口没有明确采用它,它也会“符合”该协议。您可以在代码中测试协议一致性(使用 -conformsToProtocol:),如下所示:
if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
...
}
注意:Apple 的文档指出:
“此方法仅根据头文件中的正式声明确定一致性,如上图所示。它不会检查协议中声明的方法是否实际实现 - 这是程序员的责任。
从Objective-C 2.0(在OS X 10.5“Leopard”和iOS中)开始,正式协议现在可以定义可选方法,并且只要类实现了所有必需的方法,它就符合协议。可以使用(默认值)和关键字来切换是否必须或可以实现以下方法声明以符合协议。(请参阅 Apple 的 Objective-C 2.0 编程语言指南中讨论可选协议方法的部分。@required
@optional
可选的协议方法为开发人员提供了很大的灵活性,特别是对于实现委托和侦听器。与其扩展像MouseInputAdapter这样的东西(这可能很烦人,因为Java也是单继承)或实现许多毫无意义的空方法,你可以采用一个协议,只实现你关心的可选方法。使用此模式,调用方在调用方法(使用 -respondsToSelector)之前检查该方法是否已实现,如下所示:
if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
[myObject fillArray:anArray withObject:foo];
...
}
如果反射开销成为问题,您始终可以缓存布尔结果以供重用,但要避免过早优化的冲动。:-)
它们几乎完全相同。然而,让我印象深刻的一件事是,除非您明确声明目标C协议也实现了NSObject,否则对该协议的引用无法访问NSObject声明的方法(无论如何没有编译器警告)。使用java,您可以引用接口,并且仍然可以在其上调用String()等。
例如
目标C:
@protocol MyProtocol
// Protocol definition
@end
id <MyProtocol> myProtocol;
[myProtocol retain] // Compiler warning
爪哇岛:
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