I'm writing signal processing library,
and I want to make this kind of hierarchy.
First, I defined abstract class
that define only "this wrapper class has one double[] field"
i.e.
public abstract class DoubleArray{
private final double[] array;
DoubleArray(double[] array){
this.array = array;
}
}
(I made constructor package private rather than protected because
I want to restrict usage of constructor outside the package)
(System.arraycopy is not used here
because this constructor is used only by me.)
Next, my first restriction is,
"cannot contain exceptional values"
i.e.
//inside the same package
public class SignalWithoutExceptionalValues extends DoubleArray{
SignalWithoutExceptionalValues(double[] signal){
super(signal);
for(double d : signal)
if(Double.isNaN(d) || Double.isInfinite(d))
throw new IllegalArgumentException("cannot contain exceptional values");
}
}
Next restriction is
"signal is in range of -1.0 ~ 1.0"
i.e.
//inside the same package
public final class OneAmplitudeSignal extends SignalWithoutExceptionalValues{
OneAmplitudeSignal(double[] signal){
super(signal);
for(double d : signal)
if(d > 1.0 || d < -1.0)
throw new IllegalArgumentException("is not normalized");
}
}
However, I think,
first of all,
I have to do for-each argument checking,
and then, after that,
assign to field.
but in this example,
I am forced to assign unchecked array to field,
because DoubleArray constructor must initialize array field.
So, my question is,
is there any strategy to do "first checking then assign"
in this kind of hierarchy.
OR this design is not appropriate for this purpose,
and there is another good design ?
Thank you.
EDIT
thank you for first two answers.
but by those solution,
library user can instantiate "illegal" signal,
because "checking mechanism can be overrided" .
However, I perfer inheritance
because OneAmplitudeSignal object can be
assigned to SignalWithoutExceptionalValues variables.
This fact corresponds to OneAmp~ is subset of SignalWithout~.
Also, amplitude can be checked by someSignal instanceof OneAmplitudeSignal .
And "final" can't be used here
because I want to allow library users
to create new "more restricted signal"
or, "new kind of restriction" .
In addition, root class can be non-abstract .
in this case, "no restriction signal" can also be instantiated.
MinusOneToOneSignalis more appropriate. Is there more simple name?