Reputation: 115
I am writing a Java class to represent a range. I would like to make it more general so that the range can be any Number type, but the two values v1 and v2, must be in the same Number type.
Although I can do comparison on them, I cannot add or subtract the values. I know the operation on two different number types cause problem (e.g. Float + Integer), and so do subclasses of Number, e.g. BigInteger and BigDecimal. But in my case, v1 and v2 should be of the same type.
class Range<T extends Number & Comparable<T>> {
public T v1;
public T v2;
public Range(T v1, T v2) {
if (v1.compareTo(v2) > 0)
throw new IllegalArgumentException("Value-1 must be smaller or equal to Value-2.");
this.v1 = v1;
this.v2 = v2;
}
public T length() {
return v2 - v1; // Compilation error
}
}
Recently I only come up with an idea like this:
public T add(T t1, T t2) {
if (t1 instanceof Integer) {
// ...
}
if (t1 instanceof Long) {
// ...
}
}
But is there any better design to create the Range class? Thanks!
Upvotes: 2
Views: 122
Reputation: 15212
Make Range
and length()
abstract. Also note that v1
and v2
should be protected.
abstract class Range<T extends Number & Comparable<T>> {
protected T v1;
protected T v2;
public Range(T v1, T v2) {
if (v1.compareTo(v2) > 0)
throw new IllegalArgumentException("Value-1 must be smaller or equal to Value-2.");
this.v1 = v1;
this.v2 = v2;
}
public abstract T length();
}
extend
the range class for specific types :
class IntegerRange extends Range<Integer> {
@Override
public Integer length() {
return v2 - v1;
}
}
This is in line with the open-closed
principle. A class should be open for extension, but closed for modification. Using instanceof
checks is the easiest way to go against this principle since Range
will need to modified for each new type that it has to support. This should be avoided in your case.
Upvotes: 2