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

什么是Java代替Cocoa代理?

(我知道我可以将一个接口传递给一个类,并让该类调用适当的方法,但我想知道是否还有其他方法可以实现更接近Cocoa / Objective-C的非正式协议)

简短的回答是,Java中没有任何东西可以像你想的那样接近,但也有其他选择。 委托模式并不难实现,它只是不如使用Objective-C那样方便。

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

Objective-C 2.0选择了@optional协议方法,这是一种更清晰的抽象,是新代码的首选,但更远离Java中的等价。

老实说,最灵活的方法是定义委托协议,然后让类实现所有方法。 (使用像Eclipse这样的现代IDE,这很简单。)许多Java接口都有一个附带的适配器类,这是一种不需要用户实现大量空方法的常用方法,但它限制了inheritance,这使得代码设计不灵活。 (Josh Bloch在他的书“Effective Java”中解决了这个问题。)我的建议是首先只提供一个接口,然后在真正需要的时候添加一个适配器。

无论你做什么, UnsupportedOperationException避免为“未实现”的方法抛出UnsupportedOperationException 。 这会强制委托类处理应该是可选方法的exception。 正确的方法是实现一个不执行任何操作,返回默认值等的方法。对于没有void返回类型的方法,应该很好地记录这些值。

我能想到的非正式协议的最佳模拟是一个接口,它还有一个适配器类,允许实现者避免实现每个方法。

 public class MyClass { private MyClassDelegate delegate; public MyClass () { } // do interesting stuff void setDelegate(MyClassDelegate delegate) { this.delegate = delegate; } interface MyClassDelegate { void aboutToDoSomethingAwesome(); void didSomethingAwesome(); } class MyClassDelegateAdapter implements MyClassDelegate { @Override public void aboutToDoSomethingAwesome() { /* do nothing */ } @Override public void didSomethingAwesome() { /* do nothing */ } } } 

然后有人可以来实现他们关心的东西:

 class AwesomeDelegate extends MyClassDelegateAdapter { @Override public void didSomethingAwesome() { System.out.println("Yeah!"); } } 

无论是那种,还是称为“已知”方法的纯粹reflection。 但那太疯狂了。

没有什么可以阻止你在Java对象中使用委托模式(它不像在Cocoa中那样是JDK中常用的模式)。 只需要一个符合WhateverDelegate接口类型的delegate ivar,然后在您想要委派的实例方法中,将方法调用转发到委托对象(如果存在)。 你可能会得到一些看起来很像这样的东西,除了Java而不是Obj-C。

就可选接口而言,这将更加困难。 我建议声明接口,声明一个将可选方法实现为空方法的抽象类,然后inheritance抽象类,覆盖您希望此特定对象实现的可选方法。 由于Java中缺少多重inheritance,因此存在潜在的严重限制,但这与我能想到的一样接近。