Coding on Point interfaces/superclasses instead of implementations From pretty much any book I've read it always said to code on interfaces/superclasses and rarely on implementations, today though that advice made a bit confused about how I should format my code.
Questions:

Should I be using Point2DAdvanced or Point2D.Double in the the methods of MedianPoint (like JavaRDD&lt;&gt;, the 2 private methods, the variables)? Same goes for FlagPointPairProducer.
Should I be using MedianPoint or Point2D.Double in the FlagPointPairProducer class?
Should I store the MedianPoint from the static method in a MedianPoint or Point2D.Double?

The Code:
First off I have a MedianPoint class which extends Point2D.Double. This class is responsible for outputting a median point out of a collection of points (for now only an RDD).
public class MedianPoint extends Point2D.Double {

    public MedianPoint(double x, double y) {
        super(x, y);
    }
    
    public static MedianPoint fromPointRDD(JavaRDD&lt;Point2DAdvanced&gt; points) {
        Point2DAdvanced biggestPointByXDimension = points.reduce((a, b) -&gt; getBiggestPointByXDimension(a, b));
        Point2DAdvanced biggestPointByYDimension = points.reduce((a, b) -&gt; getBiggestPointByYDimension(a, b));

        double xDimensionMedian = biggestPointByXDimension.getX() / 2.0;
        double yDimensionMedian = biggestPointByYDimension.getY() / 2.0;

        return new MedianPoint(xDimensionMedian, yDimensionMedian);
    }

    private static Point2DAdvanced getBiggestPointByXDimension(Point2DAdvanced first, Point2DAdvanced second) {
        return first.getX() &gt; second.getX() ? first : second;
    }

    private static Point2DAdvanced getBiggestPointByYDimension(Point2DAdvanced first, Point2DAdvanced second) {
        return first.getY() &gt; second.getY() ? first : second;
    }
}

I also have a FlagPointPairProducer class which according to a median point it calculates a subspace flag for a given Point2DAdvanced (another Point2D.Double extension) and returns a tuple of the flag and the point.
public class FlagPointPairProducer implements Serializable {

    private final Point2D.Double medianPoint;

    public FlagPointPairProducer(Point2D.Double medianPoint) {
        this.medianPoint = medianPoint;
    }

    public Tuple2&lt;PointFlag, Point2DAdvanced&gt; getFlagPointPair(Point2DAdvanced point) {
        PointFlag flag = calculateFlag(point);
        return new Tuple2&lt;&gt;(flag, point);
    }

    private PointFlag calculateFlag(Point2DAdvanced point) {
        double x = point.getX();
        double y = point.getY();
        double medianX = medianPoint.getX();
        double medianY = medianPoint.getY();

        int xBit = x &lt; medianX ? 0 : 1;
        int yBit = y &lt; medianY ? 0 : 1;

        return new PointFlag(xBit, yBit);
    }
}

So I can initialize a FlagPointPairProducer like so:
Point2D.Double medianPoint = MedianPoint.fromPointRDD(points);
FlagPointPairProducer producer = new FlagPointPairProducer(medianPoint);


Code requested for Point2DAdvanced:
public class Point2DAdvanced extends Point2D.Double implements Serializable {

    public Point2DAdvanced(double x, double y) {
        super(x, y);
    }

    public boolean dominates(Point2D.Double point) {
        return (x &lt;= point.getX() &amp;&amp; y &lt; point.getY())
                || (y &lt;= point.getY() &amp;&amp; x &lt; point.getX());
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append('(').append(x).append(&quot;, &quot;).append(y).append(')');
        return builder.toString();
    }

    public static Point2DAdvanced fromTextLine(String textLine, String delimiter) {
        textLine = textLine.trim();
        String[] lineArray = textLine.split(delimiter);
        double x = java.lang.Double.parseDouble(lineArray[0]);
        double y = java.lang.Double.parseDouble(lineArray[1]);
        return new Point2DAdvanced(x, y);
    }
}
Inheritance is not to be taken lightly. Have you considered composition instead? 

The MedianPoint class seems to represent a point that happens to be median in some collection of points. But this depends on the context. There is nothing in this class that could prevent creating points that are not in fact at the median. You can certainly call the constructor or a factory method with parameters that don't correspond to a median point. As such, it would make more sense to use regular point objects, and distinguish them from non-median points by naming.

The methods in this class can be static methods in a PointUtils good old fashioned utility class.

The same goes for Point2DAdvanced as well. So the answer to all your questions: use Point2D.Double everywhere. The custom point classes don't really add value, and do nothing to help reducing complexity.