制作一个类,该类扩展了Clojure中的重写类

inv*_*kat 4 java oop jvm clojure

我有非常简单的Java代码:

public class MessageListenerExample extends ListenerAdapter
{
    @Override
    public void onMessageReceived(MessageReceivedEvent event)
    {
        // do something with event
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Pio*_*dyl 10

您可以使用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
Run Code Online (Sandbox Code Playgroud)


Yur*_*ber 6

根据您需要执行的操作,有以下几种选择:

  1. 如果您确实需要在Clojure中扩展一个类(而不是Object),则可以使用gen-class来实现,请参见https://clojuredocs.org/clojure.core/gen-class。最好使用ns宏,例如
(ns your.class.Name
    :extends whatever.needs.to.be.Extended)

(defn -methodYouOverride   ; mind the dash - it's important
    [...] ...)
Run Code Online (Sandbox Code Playgroud)

除非绝对必要,否则我不建议您走这条路。正确进行编译(包括AOT编译)非常棘手。最后,您仍然需要使用Java interop来处理此类的对象,因此不确定是否值得麻烦,这使我想到了:

  1. 用Java编写代码,并使用Java interop对其进行处理。

  2. 如果您实际上需要创建实现某个接口的对象的实例,那么它会更容易:

(reify
   InterfaceYouImplement
   (methodYouImplement [..] ..)
Run Code Online (Sandbox Code Playgroud)

我在我的代码中使用它,用Java编写的代码确实要好得多。