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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/990360/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 21:56:02  来源:igfitidea点击:

Differences between Java interfaces and Objective-C protocols?

javaobjective-c

提问by Arne Evertsson

I know Java, and now I'm learning Objective-C. What exactly are the differences between Java interfaces and Objective-C protocols?

我知道 Java,现在我正在学习 Objective-C。Java 接口和 Objective-C 协议之间到底有什么区别?

采纳答案by Quinn Taylor

First off, a little historical perspective on the topic, from one of the creators of Java. Next, Wikipedia has a moderately helpful section on Objective-C protocols. In particular, understand that Objective-C supports both formal protocols(which are explicitly declared with the @protocolkeyword, the equivalent of a Java interface) and informal protocols(just one or more methods implemented by a class, which can be discovered via reflection).

首先,从 Java 的创造者之一对这个话题的历史观点。接下来,维基百科有一个关于 Objective-C 协议的适度有用的部分。特别要理解的是,Objective-C 支持正式协议(用@protocol关键字显式声明,相当于 Java 接口)和非正式协议(仅由一个类实现的一个或多个方法,可以通过反射发现)。

If you adopt a formal protocol (Objective-C terminology for "implement an interface") the compiler will emit warnings for unimplemented methods, just as you would expect in Java. Unlike Java (as skaffmanmentioned), if an Objective-C class implements the methods contained in a formal protocol, it is said to "conform" to that protocol, even if its interface doesn't explicitly adopt it.You can test protocol conformance in code (using -conformsToProtocol:) like this:

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

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

NOTE: Apple's documentationstates:

注意:Apple 的文档说明:

"This method determines conformance solely on the basis of the formal declarations in header files, as illustrated above. It doesn't check to see whether the methods declared in the protocol are actually implemented—that's the programmer's responsibility."

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

As of Objective-C 2.0 (in OS X 10.5 "Leopard" and iOS), formal protocols can now define optional methods, and?a class conforms to a protocol as long as it implements all the required methods. You can use the @required(default) and @optionalkeywords to toggle whether the method declarations that follow mustor maybe implemented to conform to the protocol. (See the section of Apple's Objective-C 2.0 Programming Languageguide that discusses optional protocol methods.)

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

Optional protocol methods open up a lot of flexibility to developers, particularly for implementing delegatesand listeners. Instead of extending something like a MouseInputAdapter(which can be annoying, since Java is also single-inheritance) or implementing a lot of pointless, empty methods, you can adopt a protocol and implement only the optional methods you care about. With this pattern, the caller checks whether the method is implemented before invoking it (using -respondsToSelector) like so:

可选的协议方法为开发人员提供了很大的灵活性,特别是对于实现委托侦听器。与其扩展像MouseInputAdapter这样的东西(这可能很烦人,因为 Java 也是单继承的)或实现许多毫无意义的空方法,您可以采用协议并仅实现您关心的可选方法。使用这种模式,调用者会在调用之前检查该方法是否已实现(使用-respondsToSelector),如下所示:

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

If the overhead of reflection becomes a problem, you can always cache the boolean result for reuse, but resist the urge to optimize prematurely. :-)

如果反射的开销成为一个问题,您总是可以缓存布尔结果以供重用,但要抵制过早优化的冲动。:-)

回答by Tom Jefferys

They are almost identical. However the one thing that has caught me out, is that unless you explicitly declare that an objective C protocol also implements NSObject, references to that protocol don't get access to the methods that NSObject declares (without a compiler warning anyway). With java you can have a reference to an interface, and still call toString() etc on it.

它们几乎相同。然而,让我感到困惑的一件事是,除非您明确声明目标 C 协议也实现了 NSObject,否则对该协议的引用无法访问 NSObject 声明的方法(无论如何都没有编译器警告)。使用 java,您可以引用一个接口,并仍然在其上调用 toString() 等。

eg

例如

Objective C:

目标 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.

Objective C (fixed):

目标 C(固定):

@protocol MyProtocol <NSObject>
// Protocol definition
@end

id <MyProtocol> myProtocol;

[myProtocol retain] // No Warning