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”.