Абстрактный класс со значением по умолчанию
Я пытаюсь определить абстрактный класс Range, который будет служить базовой реализацией ряда классов диапазонов. Предполагаемое использование не имеет значения для этого вопроса, но до сих пор я:
/**
* 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 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;
}
}
Теперь я хочу добавить конструктор с тем, который принимает только start
и stop
, и устанавливает значение шага по умолчанию 1
, независимо от того, какая реализация Number
T
(например, если T
Integer
[one]
будет иметь значение 1
, а если T
есть Long
[one]
, будет иметь значение 1L
и т.д.). Мне хотелось бы что-то вроде:
protected Range(T start, T stop) {
this(start, stop, [one]);
}
но я не могу понять, как это установить значение [one]
. Поскольку Java по-прежнему для меня совершенно новичок, я пробовал:
private static final T one = 1;
который не работает, потому что T
, очевидно, определен в инстанцировании Range.this
. Также я пробовал:
protected static abstract T getOne();
который также не работает, потому что T
определяется в экземпляре Range.this
plus static
и abstract
не работает вместе.
Мне нужно каким-то образом расширить классы, чтобы они были вынуждены определять значение [one]
независимо от того, какая реализация Number
Range
реализована для.
В конечном итоге я также хотел бы установить нулевое значение как начало по умолчанию, так что я получаю конструктор, который выглядит так:
protected Range(T stop) {
this([zero], stop, [one]);
}
Ответы
Ответ 1
Одним из решений было бы запросить подклассы для шага по умолчанию:
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;
}
}
Ответ 2
Вы можете использовать эту реализацию:
protected Range(T start, T stop) {
this(start, stop, (T) (new Integer(1)));
}
Ответ 3
У вас возникнут другие проблемы... но вот ваш номер 1:
Number ONE = new Number() {
@Override
public int intValue() {
return 1;
}
@Override
public long longValue() {
return 1L;
}
@Override
public float floatValue() {
return 1.0f;
}
@Override
public double doubleValue() {
return 1.0;
}
@Override
public byte byteValue() {
return 1;
}
@Override
public short shortValue() {
return 1;
}
};