Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a class that extends a class with overriding in clojure

I've got pretty simple java code:

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

However, I can't seem to understand how to turn that code into clojure code. The docs and articles are very confusing. I'd be happy to see more examples too. I'm also interested in using implements.

like image 275
invisible meerkat Avatar asked Jul 25 '16 16:07

invisible meerkat


2 Answers

You can use proxy to extend an existing Java class and also implement interfaces. For example:

(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
like image 84
Piotrek Bzdyl Avatar answered Sep 30 '22 05:09

Piotrek Bzdyl


Depending on what you need to do, a few options:

  1. If you really need to extend a class (other than Object) in Clojure, then you can do it using gen-class, see https://clojuredocs.org/clojure.core/gen-class. Preferably using ns macro, like
(ns your.class.Name
    :extends whatever.needs.to.be.Extended)

(defn -methodYouOverride   ; mind the dash - it's important
    [...] ...)

I wouldn't recommend going down this path unless absolutely necessary. Getting compilation right (including AOT compilation) is tricky. And in the end you still need to use Java interop to work with the objects of this class, so not sure it's worth the hassle, which brings me to:

  1. Code it in Java and use Java interop to work with it.

  2. If you actually need to create an instance of an object that implements a certain interface, then it's easier:

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

I use it around my code, it's really much nicer that coding in Java.

like image 33
Yuri Steinschreiber Avatar answered Sep 30 '22 04:09

Yuri Steinschreiber