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

2022-09-04 21:02:17

Java相当于Cocoa委托是什么?

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


答案 1

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

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

Objective-C 2.0选择了@optional协议方法,这是一个更干净的抽象,并且对于新代码来说是首选的,但与Java中的等效方法更进一步。

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

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


答案 2

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

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!");
    }
}

要么是这样,要么是纯粹的反射调用“已知”方法。但这太疯狂了。