Tutorial of J2S in Eclipse (3): Inheritance Example by User and Pet -- We Need This Complexity

Zhou Renjian
Jan 15, 2006

This article demostrates how to use up the refactor abilities of Eclipse JDT to manage sources for Java2Script Application. This article also makes further explainations of Java2Script class inheritance.

Prerequisite

Please read previous tutorials:

Writing/Refactoring Java classes in Eclipse JDT

In the previous tutorial, a class SimpleUser is created. Now I will demostrate how to refactor the orginal SimpleUser into a reusable class.

The following is the hierarchies of new J2SUser:

ISex
  + SexSensible
    + J2SUser

The interface of ISex is just an interface with two constants:

public interface ISex {
public static int FEMALE = 2;
public static int MALE = 1;
}

The class SexSensible implements the ISex as following:

public class SexSensible implements ISex {
private int sex;
}
with following methods:
public int getSex();
public int setSex(int);
public String getAdjective();
public String getLeadingAdjective();
public String getLeadingPronoun();
public String getPronoun();
private static String capitalize(String);
The full source of the class is here.

The class J2SUser extends the class SexSensible:

public class J2SUser extends SexSensible {
private String name;
private String email;
private int age;
}
with constructors:
public J2SUser();
public J2SUser(String);
public J2SUser(String, String, int, int);
and with methods:
public int getAge();
public String getEmail();
public String getName();
public void setAge(int);
public void setEmail(String);
public void setName(String);
public String toString();
The source of J2SUser is here.

It's easy for you to refactor the class SimpleUser into the above inteface and classes. You may do as following:

As the class use in this tutorial is rather simple, you may actually create complete new interfaces and classes. If there are already complicated classes existed, you should find out that using the refactoring abilities of JDT will give you convience to manage your sources and your class hierarchies.
refactor menu of Eclipse JDT

Once you finish these refactored codes, try to create a new HelloJ2SUser with main method to print out messages such as:

public class HelloJ2SUser {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("J2S inheritance version:");

J2SUser josson = new J2SUser("josson", null, 24, J2SUser.MALE);
josson.setEmail("josson@smith");
System.out.println(josson);

J2SUser kelly = new J2SUser("kelly");
kelly.setSex(J2SUser.FEMALE);
System.out.println(kelly);
}
}

Running HelloJ2SUser in Java Application mode first. As you may find some errors in running HelloJ2SUser, you have the debug abilities of Eclipse JDT, so you can find out what is wrong with your codes in JDT debug perspective before digging efforts into those JavaScript codes, which there are lack of efficient debuging tool for JavaScript codes.

Once HelloJ2SUser is passed in Java Application mode, try to run in Java2Script Application mode. But keep in mind (as mentioned in tutorial 2), you may need to re-order the classpath before you can get the Java2Script Application correctly run. Here is the classpath screenshot of HelloJ2SUser, you may re-order or delete some of the classes.
Re-order of classpath in HelloJ2SUser J2S Application

You may got the following message in the console:

J2S inheritance version:
This is user josson, he is 24 years old. He has an email josson@smith.
This is user kelly, her age is unkown. She has no email at this time.
You can aslo visit the HelloJ2SUser online demo.

Further examples for J2S class inheritance

OK, we see that J2S does support Java class inheritance. But we want to make some more examples:

public class J2SPet extends SexSensible;

Outline of J2SPet:

age : int
name : String
J2SPet()
J2SPet(String)
J2SPet(String, int)
getAdjective()
getAge()
getName()
getPronoun()
setAge(int)
setName(String)
toString()

The method getPronoun() and getAdjective() will override the original methods in SexSensible as following:

public String getPronoun() {
return "it";
}

public String getAdjective() {
return "its";
}
and toString() will override the toString() in Object:
public String toString() {
String str = "This is pet " + name + ". ";
if (age > 0) {
str += getLeadingPronoun() + " is " + age + " months old. ";
} else {
str += getLeadingAdjective() + " age is unkown. ";
}
return str;
}
The source of J2SPet is here.

And another further class J2SDog:

public class J2SDog extends J2SPet;

Outline of J2SDog:

color : String
J2SDog()
J2SDog(String)
J2SDog(String, int)
J2SDog(String, int, String)
getColor()
setColor(String)
toString()

The method toString() will override the toString() of J2SPet as following:

public String toString() {
String str = super.toString();
if (color != null && color.length() != 0) {
str += getLeadingPronoun() + " has " + color + " furs. ";
} else {
str += getLeadingAdjective() + " fur color is not mentioned. ";
}
return str;
}
The source of J2SDog is here.

One thing should be mentioned, the line:

String str = super.toString();
is calling method toString() in J2SPet.

Make some main methods to show the example of J2SPet and J2SDog:

public class HelloJ2SPet {
public static void main(String[] args) {
J2SPet bb = new J2SPet("baibai", 24);
System.out.println(bb);

J2SPet ww = new J2SPet("wangwang");
ww.setSex(ISex.FEMALE);
System.out.println(ww);
}
}
public class HelloJ2SPetDog {
public static void main(String[] args) {
J2SDog bb = new J2SDog("baibai", 24);
bb.setColor("black");
System.out.println(bb);

J2SDog ww = new J2SDog("wangwang");
ww.setSex(ISex.FEMALE);
System.out.println(ww);
}
}

The message in J2S console will be the same message in Java console as:

This is pet baibai. It is 24 months old.
This is pet wangwang. Its age is unkown.
and
This is pet baibai. It is 24 months old. It has black furs.
This is pet wangwang. Its age is unkown. Its fur color is not mentioned.
You can aslo visit the HelloJ2SPet online demo and HelloJ2SPetDog online demo.

By these example, we show that J2S does implement the Java class inheritance, including interface, static members and methods, override, polymorphism, supper calling stack, and others.

Details of Java2Script inheritance technologies

Let's review these technologies int Java2Script:

Following, we will see the inside details of Java2Script in implementing of Java class inheritance.

interface:
Interface of ISex
Sample lines from ISex.js:

Clazz.declarePackage ("net.sf.j2s.hello");
net.sf.j2s.hello.ISex = function () {
}; net.sf.j2s.hello.ISex.__CLASS_NAME__ = net.sf.j2s.hello.ISex.prototype.__CLASS_NAME__ = "net.sf.j2s.hello.ISex";
net.sf.j2s.hello.ISex.FEMALE = 2;
net.sf.j2s.hello.ISex.MALE = 1;

And what about the class SexSensible? Two sample lines is here:

net.sf.j2s.hello.SexSensible.__CLASS_NAME__ = net.sf.j2s.hello.SexSensible.prototype.__CLASS_NAME__ = "net.sf.j2s.hello.SexSensible";
Clazz.implementOf (net.sf.j2s.hello.SexSensible, net.sf.j2s.hello.ISex);

The important line is "Clazz.implementOf (...)", actually user do not need to know what happens inside the Clazz.implementOf () right now. Later tutorial will give you details. Or once you can't wait, study the source of j2slib/j2s-core-bare.js yourself.

static members:
member FEMALE and MALE in SimpleUser
Sample lines from SimpleUser.js:

net.sf.j2s.hello.SimpleUser = function () {
this.FEMALE = net.sf.j2s.hello.SimpleUser.FEMALE;
this.MALE = net.sf.j2s.hello.SimpleUser.MALE;
...
net.sf.j2s.hello.SimpleUser.__CLASS_NAME__ = net.sf.j2s.hello.SimpleUser.prototype.__CLASS_NAME__ = "net.sf.j2s.hello.SimpleUser";
net.sf.j2s.hello.SimpleUser.FEMALE = 2;
net.sf.j2s.hello.SimpleUser.MALE = 1;

As a matter of Java static member usage: you can use the static member in ways like:

SimpleUser user = new SimpleUser (); System.out.println (user.FEMALE); // should be used as SimpleUser.FEMALE

In order to support usage of "user.FEMALE", the above lines:

this.FEMALE = net.sf.j2s.hello.SimpleUser.FEMALE;
this.MALE = net.sf.j2s.hello.SimpleUser.MALE;
are inserted in the SimpleUser function body.

And the last two lines:

net.sf.j2s.hello.SimpleUser.FEMALE = 2;
net.sf.j2s.hello.SimpleUser.MALE = 1;
is just intializing the value of the static members.

override:
The method getPronoun() and getAdjective() override the original methods in SexSensible.
Lines from J2SPet.js:

Clazz.defineMethod (net.sf.j2s.hello.J2SPet, "getPronoun",
function () {
return "it";
});
Clazz.defineMethod (net.sf.j2s.hello.J2SPet, "getAdjective",
function () {
return "its";
});
Actually, there are hidden tricks inside the Clazz.defineMethod, so that overriding methods is correctly defined.

polymorphism:
Constructors in SimpleUser, User or J2SPet
Lines from J2SPet.js

Clazz.makeConstructor (net.sf.j2s.hello.J2SPet,
function (name, age) {
Clazz.superConstructor (this, net.sf.j2s.hello.J2SPet);
this.name = name;
this.age = age;
}, "String, Number");
Clazz.makeConstructor (net.sf.j2s.hello.J2SPet,
function (name) {
Clazz.superConstructor (this, net.sf.j2s.hello.J2SPet);
this.name = name;
}, "String");
Clazz.makeConstructor (net.sf.j2s.hello.J2SPet,
function () {
Clazz.superConstructor (this, net.sf.j2s.hello.J2SPet);
});

As you can see, parameters' types are defined as string, which is passed into Clazz.makeConstructor method. This method hidden details of how to implement polymorphism in Java2Script. And there are Clazz.superConstructor method to call super constructor, which is used to make sure that the instance is correctly created.

supper calling stack:
J2SDog's toString() calls super.toString (), which result in calling J2SPet.toString ();
The following lines from J2SDog.js show you what is translated Java code

public String toString() {
String str = super.toString();
into JavaScript
Clazz.defineMethod (net.sf.j2s.hello.J2SDog, "toString",
function () {
var str = Clazz.superCall (this, net.sf.j2s.hello.J2SDog, "toString", []);

Clazz.superCall will take four parameters. The first two parameter told Clazz.superCall about the calling environment, and the las two parameters is representing the calling objective and calling paramters.

We need this complexity

In previous article, I listed a question "Do we need this complexity?". I said I would give more exmples of J2S in Eclipse for the answer of "Is it necessary to use J2S?".

Now, I think it already demostrates the need of this complexity. As Eclipse JDT has the robust abilities of managing the Java sources, specially the ability of refactoring Java source, you can also get the ability of refactoring sources besides gaining the ability of reusing existed codes by using J2S.

I think more and more coming tutorial articles will give you more and more excited confidence about J2S. Stay tunned.

Followed articles:

Tutorial of J2S in Eclipse (4): How to Use java.util.* -- Resuing Java Codes
Tutorial of J2S in Eclipse (5): How to Use org.eclipse.swt.* -- Tour to UI
Tutorial of J2S in Eclipse (6): How to Use ajax.* -- A Simple RSS Reader

Resources

Down the net.sf.j2s.hello project files (zip) (61k)

Blog discussion

Have problems while reading through these articles? Or find some errors between the words? Or have some ideas on the Java2Script technology? Please make comments or discussions here in the blog.

About the author

Zhou Renjian: Initial contributor of Java2Script.