5

I want to have a constructor like the following.

public Attribute(String attrName, Number attrValue){
    this.name = attrName;
    this.value = attrValue;
}

In this I would like to have a method called incrementValue(Number n) which will add n to value. I know you cannot add two Number objects together due to the possible issues with casting. However, if I use a check to guarantee value and n are the same type is it possible to add these together? Or perhaps there is a better way to go about this.

Right now I am declaring instance variables of Integer and Double and assign the value to the correct type. I was wondering about expanding this to allow for any subclass of Number. Obviously I could write separate methods for each one but that seems like bad programming.

Is this possible in java? Am I going about this completely wrong?

thealfreds
  • 132
  • 8
  • What the justification for using the abstract superclass `Number`. Are you using concrete subclasses further down in your heirarchy? – Perception Apr 27 '12 at 02:48
  • @Perception I wanted to allow for as many possible types as I could allow since this is for practice/fun and might want to expand on it later. – thealfreds Apr 27 '12 at 03:06

2 Answers2

5

You could convert all Numbers to a single type (double is least-lossy):

class Attribute {

    private double value;

    public Attribute(String attrName, Number attrValue) {
        this.name = attrName;
        this.value = attrValue.doubleValue();
    }

}

But IMO you're better off just overloading the constructor; Number is really just not a terribly useful class in my experience (and I don't seem to be the only one who thinks so).

class Attribute {

    public Attribute(String attrName, int attrValue) {
        this.name = attrName;
        this.value = attrValue;
    }

    public Attribute(String attrName, double attrValue) {
        this.name = attrName;
        this.value = attrValue;
    }
}
Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • That is exactly what I have now. I was hoping to allow for BigInteger, BigDecimal, Byte, etc. After creating an incrementValue() method for each the code is a lot of copy paste. – thealfreds Apr 27 '12 at 02:54
  • Actually thinking about it, is there a good reason to include the other types? I was thinking this could possibly be stored in a database and thought I might need allow for all types. – thealfreds Apr 27 '12 at 02:57
  • 2
    To add `BigInteger` and `BigDouble`, you have to use [instance methods](http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#add(java.math.BigInteger)). **You cannot use `+`.** I would rethink your design, and whether or not you really need to support every single possible numeric type. – Matt Ball Apr 27 '12 at 02:57
  • I've written numerous applications which store numbers in a database and **not once have I ever needed to write anything like what you're trying to do.** Say, 95% of the time, all you need is `int` (or `long`) and `double`. And there is almost certainly no compelling reason to mix numeric types or write this as generically as you're trying to. So no, I cannot see a reason (unless you present one) that possibly storing a number in a database means you have to "allow all types." Yes, I am being curmudgeonly. – Matt Ball Apr 27 '12 at 02:59
  • edit: This is actually very good to hear. I am doing this as practice that I might have wanted to expand later. Thank you for the info about databases. – thealfreds Apr 27 '12 at 03:02
  • I would also be very wary of using `Integer`/`Double` instead of `int`/`double`. Unless you really do want to allow `null` as a possible value, stick with the primitives wherever possible. Obviously, this excludes collections, but that's what autoboxing is for (when you don't mind the performance hit) and [Trove Collections](http://trove.starlight-systems.com/) (when you do). – Matt Ball Apr 27 '12 at 03:04
  • 1
    Well originally I was using the Object instead of the primitive since I was using multiple instance variables for the different types and wanted to allow the value 0 but still check which value was initialized. Clearly flawed thinking and I think I will take the approach you gave and consolidate to one type. – thealfreds Apr 27 '12 at 03:10
0

No, it's not possible in Java. The best you can do is to go through all the cases of Number you know about.

I could certainly write a Number subclass for which it was impossible, though it'd be a slightly nonsensical implementation.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413