Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extend a jython class in a java class

Tags:

java

jython

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")}
}
like image 238
Davoud Taghawi-Nejad Avatar asked Jun 03 '14 02:06

Davoud Taghawi-Nejad


2 Answers

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
like image 115
Dan Getz Avatar answered Sep 22 '22 19:09

Dan Getz


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

like image 22
GrahamA Avatar answered Sep 25 '22 19:09

GrahamA