Consider a situation where a class implements the same basic behavior, methods, et cetera, but multiple different versions of that class could exist for different uses. In my particular case, I have a vector (a geometric vector, not a list) and that vector could apply to any N-dimensional Euclidean space (1 dimensional, 2 dimensional, ...). How can this class / type be defined?
This would be easy in C++ where class templates can have actual values as parameters, but we don't have that luxury in Java.
The two approaches I can think of that could be taken to solve this problem are:
Having an implementation of each possible case at compile time.
public interface Vector { public double magnitude(); } public class Vector1 implements Vector { public final double x; public Vector1(double x) { this.x = x; } @Override public double magnitude() { return x; } public double getX() { return x; } } public class Vector2 implements Vector { public final double x, y; public Vector2(double x, double y) { this.x = x; this.y = y; } @Override public double magnitude() { return Math.sqrt(x * x + y * y); } public double getX() { return x; } public double getY() { return y; } }
This solution is obviously very time consuming and extremely tedious to code. In this example it doesn't seem too bad, but in my actual code I'm dealing with vectors that have multiple implementations each, with up to four dimensions (x, y, z, and w). I currently have over 2,000 lines of code, even though each vector only really needs 500.
Specifying parameters at runtime.
public class Vector { private final double[] components; public Vector(double[] components) { this.components = components; } public int dimensions() { return components.length; } public double magnitude() { double sum = 0; for (double component : components) { sum += component * component; } return Math.sqrt(sum); } public double getComponent(int index) { return components[index]; } }
Unfortunately this solution hurts code performance, results in messier code than the former solution, and is not as safe at compile-time (it can't be guaranteed at compile-time that the vector you're dealing with actually is 2-dimensional, for example).
I am currently actually developing in Xtend, so if any Xtend solutions are available, they would also be acceptable.