Results 1 to 4 of 4
  1. #1
    Firen4000 is offline Member
    Join Date
    Jul 2012
    Posts
    2
    Rep Power
    0

    Default Generic Type Question

    Hey everyone,

    I have a problem dealing with generic type methods. I have the following:

    class Point: Is a point in an n-dimensional space. It has a float array containing the values for every dimension

    subclasses Point2/ Point3/ Point4: Are specific points with defined number of dimensions and some dimensionspecific methods (for example cross-product etc.)

    Now if I create a method Point.add(float pValue), which adds the float argument to every dimension separately, I should put it in the superclass Point since the implementation is the same for all subclasses. But the return-type of this function needs to be Point2/ Point3/ Point4 depending on what kind of subclass I am dealing with. I am not passing a class<T extends Point> or an object of the subclass to the function and thus it does not know what exactly T is.
    This is what I have so far:

    Java Code:
    public <T extends Point> T add(float pValue)
    {
        float[] tNewValues = new float[this.getValues().length];
        for (int i = 0; i < tNewValues.length; i++)
        {
            tNewValues[i] = this.getValues()[i] + pValue;
        }
        return (T) createSubClass(tNewValues);
    }
    The createSubClass() function takes the float array and creates a Point2/ Point3/ Point4 object depending on the length of the array.

    Is there any way to change the return type of the function depending on what subclass I am dealing with? So if i have an instance of Point2 and call the add function the return type is also Point2?

    I already have two solutions for this problem but they are both some kind of crappy:

    1. Create add() methods in all subclasses of Point that call the method of the superclass and have the correct return type, like this:

    Java Code:
    public class Point2 extends Point
    {
        ...
        @Override
        public Point2 add(float pValue)
        {
            return (Point2) super.add(pValue);
        }
        ...
    }
    2. Whenever i call the add() method with a Point2 object I need to typecast it to Point2 (if I dont I get a compiler error "cannot be applied to given types"):

    Java Code:
    ...
    Point2 p1 = new Point2(0.0f, 0.0f);
    Point2 p2 = (Point2) p1.add(1.0f);
    ...
    One thing I have noticed is that with solution1 i actually dont have to typecast the return value to Point2:

    Java Code:
    public Point2 add(float pValue)
    {
        return super.add(pValue);
    }
    This works without an error. But using the add() method like in solution2 i need the typecast orelse i get a compiler error.

    I am a bit confused about all this so if someone can explain and help me I would appreciate it.
    Last edited by Firen4000; 07-12-2012 at 11:56 AM.

  2. #2
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,568
    Rep Power
    12

    Default Re: Generic Type Question

    Defining subclass behaviour in a superclass seems a bit backwards. Are you really sure you need to subclass?

    Cross/dot product, translation and enlargement can all be defined for the n dimensional case, for example. [Edit] which you are doing. Sure you would get a compile time check on the dimension, but folk manage to work with arrays (assign, pass, return) without having nanny compiler worry about the array length. Have a PointDimensionException and throw it, as you would ArrayIndexException, if anything goes wrong.

    -----

    Could you post a SSCCE of the Point class, its add() method and the Point2 subclass, and say what grumbling you are getting from the compiler?

  3. #3
    Firen4000 is offline Member
    Join Date
    Jul 2012
    Posts
    2
    Rep Power
    0

    Default Re: Generic Type Question

    As far as I know cross product can only be calculated in three and seven dimensions and quaternion stuff needs 4 dimensions, thats why I made subclasses.

    Java Code:
    public abstract class Point
    {
        private float[] mValues;
    
        public Point(float[] pValues)
        {
            mValues = pValues;
        }
    
        public float[] getValues()
        {
            return mValues;
        }
        
        public <T extends Point> T add(float pAdd)
        {
            float[] tNewValues = new float[this.getValues().length];
            for (int i = 0; i < tNewValues.length; i++)
            {
                tNewValues[i] = this.getValues()[i] + pValue;
            }
            return (T) createSubClass(tNewValues);
        }
    
        public static Point createSubClass(float[] pValues)
        {
            switch (pValues.length)
            {
                case 2:
                {
                    return new Point 2(pValues);
                }
                case 3:
                {
                    return new Point3(pValues);
                }
                case 4:
                {
                    return new Point4(pValues);
                }
                default:
                {
                    return null;
                }
            }
        }
    }
    Java Code:
    public class Point3 extends Point
    {
        public Point(float[] pValues)
        {
            super(pValues);
        }
    
        public Point3 cross(Point3 pPoint)
        {
            Point3 tCross;
            ...
            return tCross;
        }
    }
    Error:
    Java Code:
      error: method setLocation in class Bla cannot be applied to given types;
      setLocation(getLocation().add(pDistance));
      required: Point3
      found: Point
      reason: actual argument Point cannot be converted to Point3 by method invocation conversion
    Another weird thing is that the add() method of Point class has a return type "Point" although I put <T extends Point> and a class does not extend itself.

    EDIT: Also I would like to keep the Point2/ Point3/ Point4 subclasses since they make the whole thing more readable and just nicer..
    Last edited by Firen4000; 07-12-2012 at 11:58 AM.

  4. #4
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,568
    Rep Power
    12

    Default Re: Generic Type Question

    As far as I know cross product can only be calculated in three and seven dimensions and quaternion stuff needs 4 dimensions, thats why I made subclasses.
    You're right, my bad.

Similar Threads

  1. Creating generic wrapper of return type
    By jackett_dad in forum Advanced Java
    Replies: 1
    Last Post: 03-16-2012, 06:53 PM
  2. Creating an array of generic type
    By colerelm in forum New To Java
    Replies: 1
    Last Post: 10-19-2011, 04:58 AM
  3. Type wildcards in Generic
    By gvm in forum New To Java
    Replies: 1
    Last Post: 10-22-2010, 05:39 PM
  4. Generic return type is not inferred in for-each loop
    By ranma173 in forum Advanced Java
    Replies: 5
    Last Post: 10-08-2010, 12:50 PM
  5. Generic collection type
    By dreuzel in forum Advanced Java
    Replies: 7
    Last Post: 12-23-2009, 07:05 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •