javaclassinheritancetype-conversionsuperclass

Is it possible to override a Point2D object from a superclass to a Point2D.Float?


I have defined a class called Entity with a Point2D object in it called pos. The class is a superclass and it's not specified if pos should be a Point2D.Float or a Point2D.Double, that's left for the inheritors to decide. The problem is I don't know how to override this object to make it a Point2D.Float (for example) without getting an error.

import java.awt.geom.Point2D;

public class Entity {
    Point2D pos;

    public Entity(Point2D pos) {
        this.pos = pos;
        //...
    }
    //...
}

import java.awt.geom.Point2D;

public class Enemy extends Entity {
    // Somehow overrite "pos" so it must be Point2D.Float within this subclass
    public Enemy(Point2D.Float pos) {
        this.pos = pos;
        //...
    }
    //...
}

I tried to simply insert the @Override annotation before declaring Point2D.Float pos;, but the virtual environment I was working on indicated that that was an illegal use of @Override. I wasn't sure what I was supposed to do and I didn't find any answers on Stack Overflow.

Thank you in advance.

Edit: Made Enemy extend Entity, sorry for the confusion.


Solution

  • You can make it generic with Point2D bound

    public class Entity<P extends Point2D> {
        P pos;
    
        public Entity(P pos) {
            this.pos = pos;
            //...
        }
        //...
    }
    

    ... and then narrow down to Point2D.Float for a subclass

    public class Enemy extends Entity<Point2D.Float> {
        public Enemy(Point2D.Float pos) {
            super(pos);
        }
    }
    

    What happens here?

    1. Superclass now declares a type parameter, it is now a generic class. This is normally used when the class can work with subjects of different types but it still makes difference which is used for specific instance. For example, List can work both with String and Integer, but list of strings is not the same thing as list of integers. So does Entity - it can work with Point2D.Float or Point2D.Double but it should be clear which one is chosen.
    2. There is an upper bound in superclass' type parameter declaration P extends Point2D. It means that superclass doesn't work with any type, but only with subtypes of Point2D. It also means that raw type Entity or wildcard type Entity<?> behaves similar to initial non-generic version of Entity. This ensures your code that already uses Entity class may be left unchanged (there will be warnings though).
    3. Subclasses of such a generic class must follow bounds declared in superclass and may choose to re-declare type parameter(s), possibly with narrowed bound...
        public class Enemy<P extends Point2D.Float> extends Entity<P>
    
    1. ...or pick explicit type.
        public class Enemy extends Entity<Point2D.Float>