Abstract class with default value
abstract, abstract-class, default-value, java
Solution
One solution would be to ask the subclasses for the default step to use:
public abstract class Range<T extends Number> {
private T start;
private T stop;
private T step;
public Range(T start, T stop, T step) {
this.start = start;
this.stop = stop;
this.step = step;
}
protected Range(T start, T stop) {
this.start = start;
this.stop = stop;
this.step = getDefaultStep();
}
protected abstract T getDefaultStep();
}
public class IntegerRange extends Range<Integer> {
public IntegerRange(Integer start, Integer stop, Integer step) {
super(start, stop, step);
}
public IntegerRange(Integer start, Integer stop) {
super(start, stop);
}
@Override
protected Integer getDefaultStep() {
return 1;
}
}
public class DoubleRange extends Range<Double> {
public DoubleRange(Double start, Double stop, Double step) {
super(start, stop, step);
}
public DoubleRange(Double start, Double stop) {
super(start, stop);
}
@Override
protected Double getDefaultStep() {
return 1d;
}
}
Problem
I am trying to define a abstract Range class which will serve as the base implementation of a number of range classes. The intended use is irrelevant for this question, but so far I have: ``` /** * Abstract generic utility class for handling ranges */ public abstract class Range<T extends Number> { // Variables to hold the range configuration private T start; private T stop; private T step; /** * Constructs a range by defining it's limits and step size. * * @param start The beginning of the range. * @param stop The end of the range. * @param step The stepping */ public Range(T start, T stop, T step) { this.start = start; this.stop = stop; this.step = step; } } ``` Now I want to add a constructor with that only takes `start` and `stop`, and sets a default step value of `1`, no matter what implementation of `Number` `T` is (e.g. if `T` is `Integer` `[one]` would have the value `1`, and if `T` is `Long` `[one]` would have the value `1L`, and so on). I would like something like: ``` protected Range(T start, T stop) { this(start, stop, [one]); } ``` but I can't figure out how so set the value of `[one]`. Since Java is still fairly new to me, I have tried with: ``` private static final T one = 1; ``` which doesn't work because `T` is obviously defined in the instantiation of `Range.this`. Also I have tried: ``` protected static abstract T getOne(); ``` which also doesn't work because `T` is defined in the instantiation of `Range.this` plus `static` and `abstract` don't work together. I need some way for extending classes to be forced to define the value of `[one]` no matter what implementation of `Number` `Range` is implemented for. Ultimately I would also like to set a zero value as default start, such that I get a constructor that looks like this: ``` protected Range(T stop) { this([zero], stop, [one]); } ```