3

I want to call a method in the super class from Clojure. I am extending a Java class using :gen-class.

(ns subclass.core (:gen-class :extends Baseclass)) (defn greet [] "Hello from core") ; how to call super.greet()? (defn -main [& args] (greet)) 

Java Baseclass

public class Baseclass { public String greet() { return "Hello from Baseclass"; } } 

Edit: as the linked example I tried

 (ns subclass.core (:gen-class :extends Baseclass :exposes-methods {greet pgreet}) (:import Baseclass)) (defn greet [] (.pgreet (Baseclass.))) (defn -main [& args]) 

But when I call (greet) I am getting the error

IllegalArgumentException No matching field found: pgreet for class Baseclass clojure.lang.Reflector.getInstanceField (Reflector.java:271) 

Is this the right way to call the super class method?

Update: Got it. We create a different method which will intern call the base class method. https://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples/Java_Interaction#genclass
NB: that's not what the linked answer says.

4
  • Your code doesn't follow the answer in the duplicate. You use (.pgreet (BaseClass .)) instead of (.pgreet this)`. There's a huge difference. Commented Dec 14, 2016 at 23:30
  • What is this arg? Isn't it the object of the class Baseclass? If not, (defn greet [this] (.pgreet this)) how do I invoke greet? What do I pass for this arg? Commented Dec 15, 2016 at 4:15
  • No, if you followed the answer given in the other question, this would be an object of a subclass of the class BaseClass. The BaseClass has no pgreet method -- it's the gen-classed on that has a pgreet method. Commented Dec 15, 2016 at 4:23
  • Possible duplicate of How to invoke superclass' method in a Clojure gen-class method? Commented Dec 15, 2016 at 4:25

1 Answer 1

1

This question has already been asked and answered.

Your example fails because your greet function tries to call the pgreet method on an instance of BaseClass. You need to create an instance of the gen-classed class.

For example, something like this:

(ns subclass.core (:gen-class :extends Baseclass :exposes-methods {greet pgreet}) (:import Baseclass)) ;; You need to define a function for the overridden method (defn greet- [this] (. this (pgreet))) (defn greet [] ;; You need to use the *gen-class*ed class, not BaseClass (. (new subclass.core) (greet)))) 
Sign up to request clarification or add additional context in comments.

5 Comments

I am getting ClassNotFoundException: subclass.core.
Did you compile the subclass.core namespace? You'll probably want to add an :aot entry to your project.clj to make this easier.
I added :aot [subclass.core] and now lein repl is not able to find Baseclass. I have :java-source-paths ["src/java"]. It's giving ClassNotFoundException: java.lang.Baseclass. Anyway thanks for the answer.
From another post, it was because of the naked class. Putting the java files in a package works fine.
In your example, why do you use the "-" as a suffix and not as a prefix in the name the first function? And what does naming the second function similarly to other ones supposed to show? Is the second function an example of a "local" function that does not get assigned as a method to the generated class?