且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java相当于Cocoa委托/ Objective-C非正式协议?

更新时间:2022-06-20 21:39:58

简短的答案是没有什么在Java中接近你想要的,但有替代品。代理模式不难实现,它不像Objective-C那么方便。

The short answer is there's nothing in Java as close as you'd like, but there are alternatives. The delegate pattern isn't hard to implement, it's just not quite as convenient as doing it with Objective-C.

非正式协议在Objective-C中工作的原因是因为语言支持类别,这允许您将方法添加到现有类而不对其进行子类化,甚至可以访问源代码。因此,大多数非正式协议是NSObject类别。这在Java中是显然不可能的。

The reason "informal protocols" work in Objective-C is because the language supports categories, which allow you to add methods to existing classes without subclassing them, or even having access to the source code. Thus, most informal protocols are a category on NSObject. This is clearly impossible in Java.

Objective-C 2.0选择@optional协议方法,这是一个更干净的抽象,并且更喜欢新的代码,

Objective-C 2.0 opts for @optional protocol methods, which is a much cleaner abstraction and preferred for new code, but even further from having an equivalent in Java.

老实说,最灵活的方法是定义一个委托协议,然后让类实现所有的方法。 (对于像Eclipse这样的现代IDE,这是微不足道的)许多Java接口都有一个附带的适配器类,这是一个常见的方法,不需要用户实现很多空方法,但它限制了继承,这使得代码设计不灵活。 (Josh Bloch在他的书Effective Java中解决了这个问题。)我的建议是先提供一个接口,然后添加一个适配器,如果真的有必要的话。

Honestly, the most flexible approach is to define a delegate protocol, then have classes implement all the methods. (With modern IDEs like Eclipse, this is trivial.) Many Java interfaces have an accompanying adapter class, and this is a common approach for not requiring the user to implement a lot of empty methods, but it restricts inheritance, which makes code design inflexible. (Josh Bloch addresses this in his book "Effective Java".) My suggestion would be to only provide an interface first, then add an adapter if it's truly necessary.

你可以避免为未实现方法引入 UnsupportedOperationException 。这强制委托类处理应该是可选的方法的异常。正确的方法是实现一个不做任何事情,返回一个默认值等的方法。对于没有void返回类型的方法,这些值应该记录良好。

Whatever you do, avoid throwing an UnsupportedOperationException for "unimplemented" methods. This forces the delegating class to handle exceptions for methods that should be optional. The correct approach is to implement a method that does nothing, returns a default value, etc. These values should be well documented for methods that don't have a void return type.