Розглянемо ситуацію, коли клас реалізує одне і те ж основне поведінку, методи тощо, але може існувати кілька різних версій цього класу для різних цілей. У моєму конкретному випадку у мене є вектор (геометричний вектор, а не список), і цей вектор може застосовуватися до будь-якого N-мірного евклідового простору (1 мірний, 2 мірний, ...). Як можна визначити цей клас / тип?
Це легко в C ++, де шаблони класів можуть мати фактичні значення в якості параметрів, але у нас немає такої розкоші в Java.
Для вирішення цієї проблеми я можу скористатися двома підходами:
Здійснення реалізації кожного можливого випадку під час компіляції.
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; } }
Це рішення, очевидно, дуже трудомістке і надзвичайно виснажливе кодування. У цьому прикладі це не здається занадто поганим, але в моєму фактичному коді я маю справу з векторами, які мають кілька реалізацій у кожному, що мають до чотирьох вимірів (x, y, z та w). Наразі у мене понад 2000 рядків коду, хоча кожному вектору дійсно потрібно 500.
Визначення параметрів під час виконання.
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]; } }
На жаль, це рішення шкодить продуктивності коду, приводить до коду messier, ніж попереднє рішення, і не є таким безпечним під час компіляції (не можна гарантувати під час компіляції, що вектор, з яким ви маєте справу, є двовимірним, наприклад).
Наразі я фактично розвиваюся в Xtend, тому, якщо є якісь рішення Xtend, вони також були б прийнятними.