代码之家  ›  专栏  ›  技术社区  ›  Debajit

Java等价的COCOA委托/ Objto-C非正式协议?

  •  13
  • Debajit  · 技术社区  · 15 年前

    什么是Java相当于可可代表?

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

    3 回复  |  直到 15 年前
        1
  •  8
  •   Quinn Taylor    15 年前

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

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

    Objul-C 2选择了“可选协议”方法,这是一种更干净的抽象,对于新代码更为可取,但在爪哇中也有更大的等价性。

    老实说,最灵活的方法是定义委托协议,然后让类实现所有方法。(使用像伊柯丽斯这样的现代IDE,这是微不足道的)。许多Java接口都有一个附带的适配器类,这是一种不需要用户实现许多空方法的通用方法,但是它限制继承,这使得代码设计不灵活。(Josh Bloch在他的书《有效Java》中提到了这一点。我的建议是先提供一个接口,然后在需要的时候添加一个适配器。

    无论你做什么,都要避免 UnsupportedOperationException 对于“未实现”的方法。这将强制委托类为应为可选的方法处理异常。正确的方法是实现一个什么都不做、返回默认值等的方法。对于没有void返回类型的方法,应该很好地记录这些值。

        2
  •  5
  •   Nick Veys    15 年前

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

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

    或者是调用“已知”方法的纯反射。但那太疯狂了。

        3
  •  2
  •   Community CDub    8 年前

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

    就可选接口而言,这将更加困难。我建议声明接口,将实现可选方法的抽象类声明为空方法,然后对抽象类进行子类化,重写希望此特定对象实现的可选方法。由于Java中缺少多重继承,这里有一个潜在的严重限制,但这和我能想到的一样接近。