7

I would like to extend a jython class in a java class

public class JavaClass extends JythonClass

how do I import the Jython class? Does it have to be compiled? A link to documentation would be already useful.

Example:

class JythonClass(threading.Thread):
def do(self):
    print("hallo")

--

public class JavaClass extends JythonClass
{
    public void hello()
    { System.out.print("hallo")}
}
Davoud Taghawi-Nejad
  • 16,142
  • 12
  • 62
  • 82
  • 1
    Extending classes in Java accomplishes two separate things: (1) making the subclass support the same interfaces as the superclass (is-a relationship), and (2) providing default implementations of those interfaces. Do you really need both (or either) of these things? A Jython class is not going to have any real "type"s aside from any Java class or interface it, itself, extends. For (2), you could always use composition instead of inheritance. – Dan Getz Jun 05 '14 at 22:38
  • You might get closest to "extending a Jython class" by "extending" a Jython *object* with a [dynamic proxy class](http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html), but that might be overkill for what your real needs are? – Dan Getz Jun 05 '14 at 22:51
  • http://www.prasannatech.net/2008/10/jython-inheritance-java.html This might be what you need – Rajarshi Goswami Jun 11 '14 at 12:17
  • @DanGetz, thats the best answer. Make it a seperate answer and I'll award (if nothing else comes up) to you – Davoud Taghawi-Nejad Jun 13 '14 at 19:34
  • Actually, I'm not sure about the dynamic proxy idea anymore. I think it might be more complicated than other solutions, and might have to depend on the internals of Jython. – Dan Getz Jun 14 '14 at 19:38

2 Answers2

9

You can extend a Jython class in Java such that the result is usable in Jython by creating a Jython class that extends both the Java "subclass" and the Jython "superclass". Let's say you have this Jython class:

class JythonClass(object):
    def get_message(self):
        return 'hello'
    def print_message(self):
        print self.get_message()

You can create your Java class, partially, without extending anything:

public class JavaClass {
    private String message;
    public String get_message() {
        return message;
    }
    protected JavaClass(String message) {
        this.message = message;
    }
}

And then cause the "extending" relationship in Jython:

from javapackage import JavaClass as _JavaClass
from jythonpackage import JythonClass

class JavaClass(_JavaClass, JythonClass):
    pass

Now this will work:

obj = JavaClass('goodbye')
obj.print_message()

If instead you wish to extend a Jython class in Java, and use it like a normal Java class, the easiest way would be to use composition, instead of inheritance:

  • create a Java interface for the methods on your Jython class
  • make your Jython class extend the Java interface (either by directly modifying your Jython class code, or by something like what I explained above)
  • create your Java subclass as implementing the interface, with an instance of the Jython "superclass" as a private field
  • any method in your Java subclass that you don't wish to override, just call that method on the private Jython instance
Dan Getz
  • 8,774
  • 6
  • 30
  • 64
2

I think that this is covered by Ch10 of The Definitive Guide to Jython

In this example the author uses an interface BuildingType this can be changed to an abstract class

public abstract class BuildingType {
 public abstract String getBuildingName();
 public abstract String getBuildingAddress();
 public abstract String getBuildingId();

 @Override
 public String toString(){
   return "Abstract Building Info: " +
     getBuildingId() + " " +
     getBuildingName() + " " +
     getBuildingAddress();
  }
}

which you can extend with your own methods, in this case I have added toString() and used it in 'print' instead of the authors original code:

public class Main {

  private static void print(BuildingType building) {
      System.out.println(building.toString());
  }

  public static void main(String[] args) {
      BuildingFactory factory = new BuildingFactory();
      BuildingType building1  =  factory.create("BUILDING-A", "100 WEST MAIN", "1")
      print(building1);
      BuildingType building2 = factory.create("BUILDING-B", "110 WEST MAIN", "2");
      print(building2);
      BuildingType building3 = factory.create("BUILDING-C", "120 WEST MAIN", "3");
      print(building3);
  }

}

You can duplicate this code using the code from CH10 of the The Definitive Guide to Jython and all credit must go to the author - I've only changed the Interface into a Abstract class.

You coluld also consider using a Java 7 Default method in the interface

GrahamA
  • 5,875
  • 29
  • 39