3

I want to make good use of polymorphism in java when implementing math operations between objects of math classes.
I got from the answers in How to add two java.lang.Numbers? that the general solution when using java.lang.Number is to know or check the real objects class and make the appropriate hardcoded conversion to float, int, etc.

But this approach actually is not very object oriented. The java language designers chose to give the java.lang.Number class and its derivatives a set of methods floatValue(), intValue() and so on.

In light of this, Is my proposed approach, below, not going to work?.

To implement mathematical operations in a seamless way I want to to rewrite the Number class Hierarchy to allow to do something like this:

MyNumber a = b.getValue() + c.getValue();  

where the real type of b and c don't matter

The base class would be:

public abstract class MyNumber {
   protected Object mValue;

   public abstract <N> N getValue();
}

And, for example, my integer class would look like:

public class MyInteger extends MyNumber {
    public MyInteger(int value) {
        mValue = value;
    }

    @Override
    public Integer getValue() {
        return (Integer) mValue;
    }
}

and similarly for MyFloat, MyDouble, etc.

Community
  • 1
  • 1
ilomambo
  • 8,290
  • 12
  • 57
  • 106
  • 1
    Try it out; you'll see that if you have two things typed as MyNumber, then Java won't be able to infer `getValue()`, and you'll get an error that amounts to the fact that `Object + Object` isn't valid Java. – yshavit Feb 18 '16 at 18:39
  • 1
    Also, consider that even if you did an OO version of numbers, you'd have symmetry issues: `myDouble.plus(myLong)` would probably return a MyDouble, whereas `myLong.plus(myDouble)` would probably return a MyLong... unless you had a second dispatch inside each `plus` implementation, which would mean that you'd have to have total control over all the subclasses (which is not the case for java.lang.Number, for instance -- anyone can come along and create a subclass of Number if they want). – yshavit Feb 18 '16 at 18:42
  • 1
    @yshavit That's the very definition of polymorphism. MyFloat and MyLong are both also MyNumber, by inheritance and as long as the result of `Float + Long` can be `constructed` into MyNumber it should be resolved. – ilomambo Feb 18 '16 at 18:52
  • 1
    Java doesn't know that one of the MyNumbers will return Float and the other will return Long -- as far as the type system is concerned, without extra inference help (ie without you knowing what they contain beforehand), the `` will fall back to `Object`. Just give it a try. :) – yshavit Feb 18 '16 at 19:02

1 Answers1

1

It will not work with different types.

public class MyInteger extends MyNumber {
    public MyInteger(int value) {
        mValue = value;
    }

    @Override
    public Integer getValue() {
        return (Integer) mValue;
    }
}

public class MyFloat extends MyNumber {
    public MyFloat(float value) {
        mValue = value;
    }

    @Override
    public Float getValue() { // first issue: types don't match. can't override
        return (float) mValue; // second issue: type won't match with other getValue methods, arithmetic will fail
    }
}

Your problem is even before the arithmetic. You'll need to use generics, or some kind of type-resolving and/or type-converting mechanis to get past this issue.

Firstly, overriding methods need to have matching signatures, and Types are part of that signature.

Secondly, after having a single type, Java does not have operator overloading. Therefore you will need to implement a method that MyNumber has that can take your two Generic or high level Object's and do that type casting or conversion itself.

Community
  • 1
  • 1
Sean Newell
  • 1,033
  • 1
  • 10
  • 25
  • You don't need to ask a question here to just try it. It's not a good idea. If you do any serious scientific computing you know that this kind of polymorphism isn't helpful. – duffymo Feb 18 '16 at 21:43