在clojure中覆盖代理中的多方法

时间:2012-10-30 07:43:11

标签: clojure overloading arity

我有一个java类,它有两个方法具有相同但不同的arities(一个不带参数,另一个带1个参数)。我创建了一个覆盖这两种方法的代理。问题是如果从这个java类调用no-arg方法 - 调用基本实现而不是代理。但是如果我直接在obj上调用no-arg方法 - 调用正确的代理方法。有人可以解释这种行为吗?

Test.java:

package example;

public abstract class Test {

    public void callMethods(Object obj){
        callMethods();
        callMethods2();
    }

    public void callMethods() {
        System.out.println("Default callMethods");
    }

    public void callMethods2() {
        System.out.println("Default callMethods2");
    }

}

run.clj:

(let [obj (proxy [example.Test] []
            (callMethods
              ([] (println "Overridden callMethods"))
              ([obj] (proxy-super callMethods obj)))
            (callMethods2
              ([] (println "Overridden callMethods2"))))]
  (.callMethods obj)
  (.callMethods obj :test))

输出:

Overridden callMethods
Default callMethods
Overridden callMethods2

预期产出:

Overridden callMethods
Overridden callMethods
Overridden callMethods2

1 个答案:

答案 0 :(得分:5)

代理维护它代理此对象的方法的映射。在这个地图中用它的方法处理的任何调用,其他调用该对象。 proxy-super通过从函数方法映射中删除自身,调用自身并将自己置于后面的语言中来实现它的神奇之处。在调用中,对代理对象的该方法的任何调用都将落入代理对象。

  • 第一行输出来自代理调用,您可以看到重写的输出
  • 第二行来自super的方法,零参数,因为当调用发生时,重写方法不在代理方法映射的对象中。
  • 第三行被代理,因为该方法位于代理方法映射的对象中。

end of this post by Meikel Brandmeyer描述了一个非常类似的场景。我怀疑答案是使用gen-class而不是代理