user3592287
user3592287

Reputation: 31

Extend java class in clojure: how to override only one of two similar methods?

I have the following java class.

public class Toto {
    public void aMethod(A a) {
        System.out.println("A " + a);   
    }

    public void aMethod(B b) {
        System.out.println("B " + b);
    }
}

I want to override aMethod(A a) but not aMethod(B b). The only way I could do that was:

(ns titi
    (:gen-class :extends Toto
     :exposes-method {aMethod parentMethod}))

(defn- -aMethod [this x]
    (if (= (type x) A)
        (println "ok do something here")
        (.parentMethod this x)))

Is there a better way to do this? (I mean without checking type of x myself).

Upvotes: 2

Views: 1330

Answers (1)

circlespainter
circlespainter

Reputation: 846

According to http://dishevelled.net/Tricky-uses-of-Clojure-gen-class-and-AOT-compilation.html, with :gen-class it is possible to override by signature but I couldn't find documentation on that, so I guess it can be considered "internals" and it may break in the future.

Anyway, supposing you have your Toto class in package jpkg together with two empty classes A and B, this works for me:

(ns Titi
(:import [jpkg A])
    (:gen-class :extends jpkg.Toto
                :exposes-method [aMethod]))

(defn- -aMethod-A [this x]
    (println "clj a"))

As the following main namespace:

(ns main
    (:import [jpkg A B]))

(set! *warn-on-reflection* true)

(defn -main []
    (. (new Titi) aMethod (new A))
    (. (new Titi) aMethod (new B)))

prints:

clj a
B jpkg.B@6631f5ca

instead of:

clj a
clj a

Type hints instead seem not to help here.

Upvotes: 1

Related Questions