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

时间:2022-09-25 12:15:18

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协议之间到底有什么区别?

2 个解决方案

#1


80  

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 @protocol keyword, 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 skaffman mentioned), 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 documentation states:

注意:苹果的文档:

"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 @optional keywords to toggle whether the method declarations that follow must or may be implemented to conform to the protocol. (See the section of Apple's Objective-C 2.0 Programming Language guide that discusses optional protocol methods.)

在Objective-C 2.0中(在OS X 10.5“Leopard”和iOS中),正式协议现在可以定义可选的方法,只要实现所有必需的方法,类就符合协议。您可以使用@required(默认)和@optional关键字来切换跟随的方法声明是否必须或可能实现以符合协议。(参见苹果的Objective-C 2.0编程语言指南,讨论可选的协议方法。)

Optional protocol methods open up a lot of flexibility to developers, particularly for implementing delegates and 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. :-)

如果反射的开销成为一个问题,您总是可以缓存布尔结果以供重用,但是不要急于过早地进行优化。:-)

#2


18  

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:

Objective - C:

@protocol MyProtocol
// Protocol definition
@end

id <MyProtocol> myProtocol;

 [myProtocol retain] // Compiler warning

Java:

Java:

public interface MyInterface {
// interface definition
}

MyInterface myInterface;

myInterface.toString();  // Works fine.

Objective C (fixed):

Objective - C(固定):

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

id <MyProtocol> myProtocol;

[myProtocol retain] // No Warning

#1


80  

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 @protocol keyword, 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 skaffman mentioned), 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 documentation states:

注意:苹果的文档:

"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 @optional keywords to toggle whether the method declarations that follow must or may be implemented to conform to the protocol. (See the section of Apple's Objective-C 2.0 Programming Language guide that discusses optional protocol methods.)

在Objective-C 2.0中(在OS X 10.5“Leopard”和iOS中),正式协议现在可以定义可选的方法,只要实现所有必需的方法,类就符合协议。您可以使用@required(默认)和@optional关键字来切换跟随的方法声明是否必须或可能实现以符合协议。(参见苹果的Objective-C 2.0编程语言指南,讨论可选的协议方法。)

Optional protocol methods open up a lot of flexibility to developers, particularly for implementing delegates and 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. :-)

如果反射的开销成为一个问题,您总是可以缓存布尔结果以供重用,但是不要急于过早地进行优化。:-)

#2


18  

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:

Objective - C:

@protocol MyProtocol
// Protocol definition
@end

id <MyProtocol> myProtocol;

 [myProtocol retain] // Compiler warning

Java:

Java:

public interface MyInterface {
// interface definition
}

MyInterface myInterface;

myInterface.toString();  // Works fine.

Objective C (fixed):

Objective - C(固定):

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

id <MyProtocol> myProtocol;

[myProtocol retain] // No Warning