My buddy Llewellyn showed me this a while back, but Java enums rock. It seems to me that in the Java/C# war whichever language gets the feature last does a better job because they see the other languages’ pain points. Enums were baked into .NET 1.0 (~2000), whereas Java got them in 2005. As a result Java did a better job.

The example they give in the tutorial is this one:

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms
    private final double radius; // in meters
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }

    public double getMass()   { return mass; }
    public double getRadius() { return radius; }

    // universal gravitational constant  (m3 kg-1 s-2)
    public static final double G = 6.67300E-11;

    double surfaceGravity() {
        return G * mass / (radius * radius);
    }

    double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }

    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage:  java Planet <earth_weight>");
            System.exit(-1);
        }
        double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight/Planet.EARTH.surfaceGravity();
        for (Planet p : Planet.values())
           System.out.printf("Your weight on %s is %f%n", p, p.surfaceWeight(mass));
    }
}

Pasted from here.

There was one syntax error in the code, and I changed a couple of other things shown in bold because I didn’t understand the point (perhaps if I was a better Java developer I might).

Let’s see what it would take to produce this in C#, shall we? I moved the main into a separate file (even in the Java world).
My first pass was this:

public class Planet
{
	public static readonly Planet MERCURY = new Planet(3.303e+23, 2.4397e6);
	public static readonly Planet VENUS   = new Planet(4.869e+24, 6.0518e6);
	public static readonly Planet EARTH   = new Planet(5.976e+24, 6.37814e6);
	public static readonly Planet MARS    = new Planet(6.421e+23, 3.3972e6);
	public static readonly Planet JUPITER = new Planet(1.9e+27, 7.1492e7);
	public static readonly Planet SATURN  = new Planet(5.688e+26, 6.0268e7);
	public static readonly Planet URANUS  = new Planet(8.686e+25, 2.5559e7);
	public static readonly Planet NEPTUNE = new Planet(1.024e+26, 2.4746e7);

	public static Planet[] values()
	{
		return new Planet[]
		{
			MERCURY,
			VENUS  ,
			EARTH  ,
			MARS   ,
			JUPITER,
			SATURN ,
			URANUS ,
			NEPTUNE,
		};
	}

	private readonly double mass;   // in kilograms
	private readonly double radius; // in meters
	private Planet(double mass, double radius)
	{
		this.mass = mass;
		this.radius = radius;
	}
	public double getMass() { return mass; }
	public double getRadius() { return radius; }

	// universal gravitational constant  (m3 kg-1 s-2)
	public static readonly double G = 6.67300E-11;

	public double surfaceGravity()
	{
		return G * mass / (radius * radius);
	}
	public double surfaceWeight(double otherMass)
	{
		return otherMass * surfaceGravity();
	}
}

Notice that I had to do explicit initialization, and I had to add the values function as well.
The only problem with this was that I didn’t get a proper ToString (or toString for the Java folks). I could just add it, but that would be tricky. Instead let me try another way, basically using the normal .NET enums to my advantage.

public enum PlanetEnum
{
	MERCURY,
	VENUS  ,
	EARTH  ,
	MARS   ,
	JUPITER,
	SATURN ,
	URANUS ,
	NEPTUNE,
}

public class Planet
{
	public static readonly Planet MERCURY = new Planet(PlanetEnum.MERCURY, 3.303e+23, 2.4397e6);
	public static readonly Planet VENUS = new Planet(PlanetEnum.VENUS, 4.869e+24, 6.0518e6);
	public static readonly Planet EARTH = new Planet(PlanetEnum.EARTH, 5.976e+24, 6.37814e6);
	public static readonly Planet MARS = new Planet(PlanetEnum.MARS, 6.421e+23, 3.3972e6);
	public static readonly Planet JUPITER = new Planet(PlanetEnum.JUPITER, 1.9e+27, 7.1492e7);
	public static readonly Planet SATURN = new Planet(PlanetEnum.SATURN, 5.688e+26, 6.0268e7);
	public static readonly Planet URANUS = new Planet(PlanetEnum.URANUS, 8.686e+25, 2.5559e7);
	public static readonly Planet NEPTUNE = new Planet(PlanetEnum.NEPTUNE, 1.024e+26, 2.4746e7);

	public static Planet[] values()
	{
		return new Planet[]
		{
			MERCURY,
			VENUS  ,
			EARTH  ,
			MARS   ,
			JUPITER,
			SATURN ,
			URANUS ,
			NEPTUNE,
		};
	}

	private readonly double mass;   // in kilograms
	private readonly double radius; // in meters
	private readonly PlanetEnum planetEnum;

	private Planet(PlanetEnum planetEnum, double mass, double radius)
	{
		this.planetEnum = planetEnum;
		this.mass = mass;
		this.radius = radius;
	}
	public double getMass() { return mass; }
	public double getRadius() { return radius; }

	// universal gravitational constant  (m3 kg-1 s-2)
	public static readonly double G = 6.67300E-11;

	public double surfaceGravity()
	{
		return G * mass / (radius * radius);
	}
	public double surfaceWeight(double otherMass)
	{
		return otherMass * surfaceGravity();
	}

	public override string ToString()
	{
		return planetEnum.ToString();
	}
}

That achieves parity, but it is ugly.

Score 1 for Java I guess…

This brought me to the end of the first three modules (OO Programming concepts, Language Basics, and Classes and Objects) in the “Learning the Java Language trail”. Next time I will continue with “Interfaces and Inheritance”.

No comments yet.

No Comments

Sorry, the comment form is closed at this time.