Reputation: 57
I have a Generic class with two data members. Here is a piece of code that I have written
class Calculator<T> {
T num1, num2;
public Calculator(T num1, T num2) {
this.num1 = num1;
this.num2 = num2;
}
}
I want to perform simple arithmetic on num1, num2 like addition and subtraction, and I also want to perform simple binary operations like < and > but as it is generic type, it's not allowed to do that.
But it's not allowed, then can anyone tell me how I can perform these tasks?
Upvotes: 0
Views: 1851
Reputation: 140318
You could provide a set of operations:
interface Operations<T> {
T add(T a, T b);
T times(T a, T b);
// ...
}
Implement for a specific type:
class IntOperations implements Operations<Integer> {
Integer add(Integer a, Integer b) { return a + b; }
Integer times(Integer a, Integer b) { return a * b; }
// ...
}
Then pass an instance of this into Calculator
:
public Calculator(T num1, T num2, Operations<T> ops) {
and invoke the method on ops
as required.
Upvotes: 0
Reputation: 102902
Not possible; and that is inherent in what you are trying to do: The job of adding 2 numbers together is not something you can just do; you can't write code that can add 2 arbitrary 'T's together.
Imagine you wrote some hypothetical code that can do it, and then I invite '2-d space complex numbers', which have a real component, and imaginary component, and a super-imaginary component: 5 + 10i + 20j
is an example of such a number. You can add any supercomplex numbers together the way you'd think; 5 + 10i + 20j
+ 1 + 2i + 3j
is 6 + 12i + 23j
.
It's obviously not possible to write code that can do this without first knowing that this supercomplex number thing I made up exists.
In other words, a Calculator
for arbitrary 'things that support addition' cannot be. You COULD build a calculator specifically for SuperComplex numbers, and have code that takes in, say, a List<T>
along with a Calculator<T>
and is thus able to produce, say, the sum:
interface Calculator<T> {
// note: Interface. You don't implement it, the user of this library does.
T add(T a, T b);
T zero();
}
class ListSummer<T> {
int sum(List<T> list, Calculator<T> calculator) {
T answer = calculator.zero();
for (T item : list) answer = calculator.add(answer, item);
return answer;
}
}
and then you can publish this library, and I can download it, and write this:
class SuperComplex {
double real, i, j;
}
class SuperComplexCalculator implements Calculator<SuperComplex> {
public SuperComplex zero() { return new SuperComplex(); }
public SuperComplex add(SuperComplex a, SuperComplex b) {
double real = a.real + b.real;
double i = a.i + b.i;
double j = a.j + b.j;
return new SuperComplex(real, i, j);
}
}
and then use your ListSummer code, passing in my calculator.
Upvotes: 0
Reputation: 4013
The short answer is you can't.
The long answer is that you can limit the type of T
to a specific type.
T extends Comparable<T>
after which you could num1.compareTo(num2)
T extends Number
, and then do arithmetic on the primitive types taken from number:int a = num1.intValue();
int b = num2.intValue();
int sum = a + b;
int diff1 = a - b;
int diff2 = b - a;
The problem with this last approach is turning the arithmetic result back to T
, you'd need to add a method for that.
Upvotes: 1