我懂Java,现在正在学习Objective-C。Java接口和Objective-C协议之间的区别是什么?
我懂Java,现在正在学习Objective-C。Java接口和Objective-C协议之间的区别是什么?
首先,由Java的创造者之一提供了一些关于此主题的历史背景。接下来,维基百科上有一个关于Objective-C协议的章节,对理解Objective-C支持的正式协议(使用@protocol
关键字显式声明,相当于Java接口)和非正式协议(只是由类实现的一个或多个方法,并可以通过反射发现)很有帮助。
如果您采用正式协议(Objective-C术语中的“实现接口”),编译器将像在Java中一样发出有关未实现方法的警告。如果Objective-C类实现了正式协议中包含的方法,则称其符合该协议,即使其接口没有明确采用该协议(这一点与Java不同,正如skaffman所提到的那样)。您可以在代码中测试协议符合情况(使用-conformsToProtocol:),例如:
if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
...
}
注意:苹果公司的文档指出:
"此方法仅基于头文件中的正式声明进行判断是否符合协议。它不会检查协议中声明的方法是否实际被实现,这是程序员的责任。"
自Objective-C 2.0(在OS X 10.5“Leopard”和iOS中)起,正式协议现在可以定义可选方法,只要类实现了所有必需的方法,就可以遵循协议。您可以使用@required
(默认)和@optional
关键字来切换后续方法声明必须或可以被实现以符合协议。(请参阅Apple的Objective-C 2.0编程语言指南中讨论可选协议方法的部分。)
可选协议方法为开发人员提供了很多灵活性,特别是用于实现代理和监听器。您可以采用协议并仅实现您关心的可选方法,而不是扩展诸如MouseInputAdapter之类的东西(这可能很烦人,因为Java也是单继承),或者实现许多无意义的空方法。使用此模式,调用者在调用它之前检查该方法是否被实现(使用-respondsToSelector):
if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
[myObject fillArray:anArray withObject:foo];
...
}
如果反射的开销成为问题,您可以随时缓存布尔结果以便重用,但要抵制过早优化的冲动。 :-)
@protocol MyProtocol
// Protocol definition
@end
id <MyProtocol> myProtocol;
[myProtocol retain] // Compiler warning
Java:
public interface MyInterface {
// interface definition
}
MyInterface myInterface;
myInterface.toString(); // Works fine.
Objective C (fixed):
@protocol MyProtocol <NSObject>
// Protocol definition
@end
id <MyProtocol> myProtocol;
[myProtocol retain] // No Warning
-conformsToProtocol:
只有在类明确采用协议时才会返回YES。你试过吗? - user102008-conformsToProtocol:
确实要求类(或祖先)正式声明采用协议。不确定我怎么会错了,感谢您的纠正! - Quinn Taylor