ingroxd
ingroxd

Reputation: 1025

Generic class - operator issue

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 doubles, floats and integers, that's why I'm trying to make a simple addiction.

Upvotes: 3

Views: 691

Answers (2)

Beryllium
Beryllium

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

Rahul Bobhate
Rahul Bobhate

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

Related Questions