创建一个扩展类的类,覆盖clojure

时间:2016-07-25 16:53:20

标签: java oop clojure jvm

我有非常简单的java代码:

public class MessageListenerExample extends ListenerAdapter
{
    @Override
    public void onMessageReceived(MessageReceivedEvent event)
    {
        // do something with event
    }
}

但是,我似乎无法理解如何将该代码转换为clojure代码。文档和文章非常令人困惑。我也很高兴看到更多的例子。我也对使用implements感兴趣。

3 个答案:

答案 0 :(得分:5)

根据您的需要,可以选择以下几种方法:

  1. 如果你真的需要在Clojure中扩展一个类(除了Object),那么你可以使用gen-class来实现它,参见https://clojuredocs.org/clojure.core/gen-class。最好使用ns宏,如
  2. (ns your.class.Name
        :extends whatever.needs.to.be.Extended)
    
    (defn -methodYouOverride   ; mind the dash - it's important
        [...] ...)
    

    除非绝对必要,否则我不建议沿着这条路走下去。正确编译(包括AOT编译)很棘手。最后你仍然需要使用Java互操作来处理这个类的对象,所以不确定它是否值得麻烦,这让我想到:

    1. 使用Java编写代码并使用Java互操作来处理它。

    2. 如果您确实需要创建一个实现某个界面的对象实例,那么它就更容易了:

    3. (reify
         InterfaceYouImplement
         (methodYouImplement [..] ..)
      

      我在代码中使用它,用Java编码真的好得多。

答案 1 :(得分:4)

您可以使用proxy扩展现有Java类并实现接口。例如:

(import '[java.awt.event ActionListener ActionEvent KeyAdapter KeyEvent])

(def listener
  (proxy
    ;; first vector contains superclass and interfaces that the created class should extend/implement
    [KeyAdapter ActionListener]
    ;; second vector contains arguments to superclass constructor
    []
    ;; below are all overriden/implemented methods
    (keyPressed [event]
      (println "Key pressed" event))
    (actionPerformed [action]
      (println "Action performed" action))))

(.keyPressed listener nil)
;; => Key pressed nil

(.actionPerformed listener nil)
;; => Action performed nil

答案 2 :(得分:1)

自己实现EventListener,而不是使用那里的适配器类为java程序员提供更方便的东西(但是对于clojure程序员来说却更难!)。您将收到一个Event对象,您可以自行检查它是否是MessageReceivedEvent的实例,就像适配器would do for you一样。

在Clojure中实现接口是通过reify完成的 - 请参阅https://stackoverflow.com/a/8615002/625403以获取示例。