dwjohnston
dwjohnston

Reputation: 11812

Declare an abstract variable with anonymous type?

I want to create an abstract Parameter class.

public abstract class Parameter{

}

I will have at least two subclasses:

public class ParamDouble extends Parameter{
    public final double MIN;
    public final double MAX;
    private double value;

    public ParamDouble(double min, double max, double current){
         this.MIN = min; 
         this.MAX = max; 
         this.value = current; 
         }



    public void setValue(double v) {
        this.value = v;
        }
    public double getValue(){
        return this.value;
        }

}

and:

public class ParamInt extends Parameter{
    public final int MIN;
    public final int MAX;
    private int value;

    public ParamDouble(int min, int max, int current){
         this.MIN = min; 
         this.MAX = max; 
         this.value = current; 
         }



    public void setValue(int v) {
        this.value = v;
        }
    public int getValue(){
        return this.value;
        }

}

So all subclasses will require, the finals MIN and MAX, and value, and contain three argument constructors, and setValue() and getValue(), but they have different types.

How can I declare these variables in the abstract class?

Upvotes: 2

Views: 417

Answers (3)

jeff
jeff

Reputation: 4333

There's a few things I would like to mention

1) You should look at java generics. This would be a good candidate for it.

 public class Parameter<T extends Number> {
   private T value;

   public Parameter(T value) { this.value = value }

   public T getValue() { return value };
 }

Then I can declare Parameters of Double or Integer.

 Parameter<Double> doubleParam = new Parameter<Double>(2.5);
 Parameter<Integer> intParam = new Parameter<Integer>(1);

2) I don't think you want to set MIN and MAX in your constructor. That will allow you to change it on the fly. For example, consider if you checked MIN and MAX before you allowed set, like

 public void setValue(T value)
 {
    if (value < MIN || value > MAX) // error
    else
      this.value = value;
 }

Now I could do something wacky like

 Parameter<Integer> i1 = new Parameter<Integer>(0, 10, 4);
 i1.set(11); // this would error, until we did

 Parameter<Integer> i2 = new Parameter<Integer>(0, 15, 4);
 i1.set(11); // now it works

If that's what you want, then fine - but it seems a little odd. You might just want to make min and max regular (non-static) members or initialize them some other way.

Upvotes: 1

Bohemian
Bohemian

Reputation: 425043

You only need a single generic class with the correct type bound:

public class Parameter<T extends Number & Comparable<T>> {
    public final T min;
    public final T max;
    private T value;

    public Parameter(T min, T max, T current) {
        this.min = min; 
        this.max = max; 
        setValue(current); // Use setter to check range on construction 
    }

    public void setValue(T v) {
        // being Comparable, we can check the range generically
        if (max.compareTo(v) < 0) { 
            throw new IllegalArgumentException("Value exceeds " + max);
        }
        if (min.compareTo(v) > 0) {
            throw new IllegalArgumentException("Value is below " + min);
        }

        this.value = v;
    }

    public T getValue() {
        return this.value;
    }
}


Explanation of <T extends Number & Comparable<T>>

The bound of T is Number & Comparable<T>, which means it must be both a Number and a Comparable<T>. This is done because Number does not implement Comparable, which has the compareTo() method, but all the java.lang.Number classes (eg Integer) do, and you need the compareTo() method to check parameter range in the setValue() method.

Without this special bound, you can't check the range generically.


The other major change was to make min and max instance variables, rather than static ones. You might consider having some static min/max values to pass into the constructor, or to implement subclasses like this:

public class IntegerParameter extends Parameter<Integer> {

     public IntegerParameter(Integer current) {
         // specify a default min/max for the Integer impl
         super(-1, 999, current); 
     }
}

Upvotes: 4

PermGenError
PermGenError

Reputation: 46418

java.lang.Number is the super class of java.lang.Integer and java.lang.Double. just make your value type as Number.

    private Number value;

    public abstract void setValue(Number v);
    public abstract Number getValue();

but your static final variables MIN and MAX if declared in the abstract class, you wont be able to inherit them in your subclass, because of they are marked static final.

Upvotes: 1

Related Questions