Reputation: 1025
I'm trying to do a generic class in Java. Reading some guides, I found how to declare it and also how to call its function as well.
My class is a point and without methods it would be in this way:
class Pnt<type>{
protected type x, y;
protected int col;
}
Now, I'm trying to make an add
method, but I am not able to do it.
What I tried is:
void add(type x_, type y_){
x += x_;
y += y_;
}
The IDE is yelling at me that +=
is undefined for type
variables...
I know that in Java isn't possible to define a new operator like in C++, so I'm asking for an alternative way to add two type
variables!
P.S. All the type that I will use would be double
s, float
s and int
egers, that's why I'm trying to make a simple addiction.
Upvotes: 3
Views: 691
Reputation: 12998
There are two problems: First, if it should be fast, you have to use primitives directly, and these are not supported as a parameter in generics. This effectively means you have to maintain three versions for Point
separately.
If you want to use generics, you can use the corresponding class (like Integer
), but there is still one problem: Their super type Number
does not have an add
method (let alone a +
operator or +=
).
So the only way I know is to implement your own numeric class hierarchy which supports an add
method:
abstract class Numeric<T extends Number> {
public abstract T getValue();
public abstract Numeric<T> add(Numeric<T> other);
@Override
public String toString() {
return getValue().toString();
}
}
class MyInt extends Numeric<Integer> {
public final Integer value;
public MyInt(Integer _value) {
super();
this.value = _value;
}
@Override
public Integer getValue() {
return this.value;
}
@Override
public Numeric<Integer> add(Numeric<Integer> other) {
return new MyInt(this.value + other.getValue());
}
}
class MyDouble extends Numeric<Double> {
public final double value;
public MyDouble(Double _value) {
super();
this.value = _value;
}
@Override
public Double getValue() {
return this.value;
}
@Override
public Numeric<Double> add(Numeric<Double> other) {
return new MyDouble(this.value + other.getValue());
}
}
Based on this you can implement at least a generic point:
class NumericPoint<T extends Number> {
public final Numeric<T> x;
public final Numeric<T> y;
public NumericPoint(Numeric<T> _x, Numeric<T> _y) {
super();
this.x = _x;
this.y = _y;
}
public NumericPoint<T> add(NumericPoint<T> other) {
return new NumericPoint<T>(this.x.add(other.x), this.y.add(other.y));
}
@Override
public String toString() {
return "(" + this.x + "/" + this.y + ")";
}
}
to be used with
NumericPoint<Integer> ip1 =
new NumericPoint<Integer>(new MyInt(1), new MyInt(2));
NumericPoint<Integer> ip2 =
new NumericPoint<Integer>(new MyInt(3), new MyInt(4));
NumericPoint<Integer> ip = ip1.add(ip2);
System.out.println(ip);
NumericPoint<Double> dp1 =
new NumericPoint<Double>(new MyDouble(1.1), new MyDouble(2.1));
NumericPoint<Double> dp2 =
new NumericPoint<Double>(new MyDouble(3.1), new MyDouble(4.1));
NumericPoint<Double> dp = dp1.add(dp2);
System.out.println(dp);
I have modified your example: The numerics and the points are immutable. It's implemented like BigDecimal
for example. So the add
method belongs to the generic class, and it returns a new instance.
Upvotes: 1
Reputation: 5082
When you say class Pnt<type>
, ti means that type
is an object and not a primitive data type like int
or double
. You can perform +=
operation on numeric primitive data types like int
, float
, etc and not on an object. In fact you can't perform the +=
operation with any generic object.
The objects of Integer
, Float
, etc. support the +=
operator, because they are wrapper classes and get unboxed to primitive types and autoboxed later. But the compiler has no way to confirm that the type
will be an Integer
or Float
. Therefore, it generates a compile time error.
Upvotes: 3