26

I have the following class, which describe one point on XY surface:

class Point{
    double x;
    double y;

    public Point(int x, int y){
        this.x = x;
        this.y = y;
    }
}

So I want to overlad + and - operators to have possibility write run following code:

Point p1 = new Point(1, 2);
Point p2 = new Point(3, 4);
Point resAdd = p1 + p2; // answer (4, 6)
Point resSub = p1 - p2; // answer (-2, -2)

How can I do it in Java? Or I should use methods like this:

public Point Add(Point p1, Point p2){
    return new Point(p1.x + p2.x, p1.y + p2.y);
}

Thanks in advance!

Håvard Geithus
  • 5,544
  • 7
  • 36
  • 51
Dmitry Belaventsev
  • 6,347
  • 12
  • 52
  • 75

6 Answers6

18

You cannot do this in Java. You'd have to implement a plus or add method in your Point class.

class Point{
    public double x;
    public double y;

    public Point(int x, int y){
        this.x = x;
        this.y = y;
    }

    public Point add(Point other){
        this.x += other.x;
        this.y += other.y;
        return this;
    }
}

usage

Point a = new Point(1,1);
Point b = new Point(2,2);
a.add(b);  //=> (3,3)

// because method returns point, you can chain `add` calls
// e.g., a.add(b).add(c)
maček
  • 76,434
  • 37
  • 167
  • 198
10

Despite you can't do it in pure java you can do it using java-oo compiler plugin. You need to write add method for + operator:

public Point add(Point other){
   return new Point(this.x + other.x, this.y + other.y);
}

and java-oo plugin just desugar operators to these method calls.

Erick Shepherd
  • 1,403
  • 10
  • 19
mart
  • 2,537
  • 1
  • 15
  • 13
  • 2
    and of course this is a stupid idea unless it's only you who would ever read your code – ACV Mar 09 '20 at 16:20
3

There is no operator overloading in Java. Apparently for reasons of taste. Pity really.

(Some people will claim that Java does have overloading, because of + with String and perhaps autoboxing/unboxing.)

Let's talk about value types.

Many early classes (and some later ones) make a right mess of this. Particularly in AWT. In AWT you should be explicitly making copies of simple values all over the place. Almost certainly you want to make value types immutable - the class should be final and it should never change state (generally all final fields pointing to effective immutables).

So:

public final class Point {
    private final int x;
    private final int y;

    private Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public static of(int x, int y) {
        return new Point(x, y);
    }

    public int x() {
        return x;
    }
    public int y() {
        return y;
    }
    public Point add(Point other) {
        return of(x+other.x, y+other.y);
    }

    // Standard fluffy bits:
    @Override public int hashCode() {
        return x + 37*y;
    }
    @Override public boolean equals(Object obj) {
        if (!(obj instanceof Point)) {
            return false;
        }
        Point other = (Point)obj;
        return x==other.x && y==other.y;
    }
    @Override public String toString() {
        return "("+x+", "+y+")";
    }
}

The original code was confused between int and double, so I've chosen one. If you used double you should exclude NaN. "Point" tends to imply an absolute point, which doesn't make sense to add. "Vector" or "dimension" would probably be more appropriate, depending upon what you intend.

I've hidden the constructor, as identity is not important. Possibly values could be cached. Possibly it is, say, common to add a point to a zero point, so no points need to be created.

It's possible you might want a mutable version, for example to use as an accumulator. This should be a separate class without an inheritance relationship. Probably not in simple cases, but I'll show it anyway:

public final class PointBuilder {
    private int x;
    private int y;

    public PointBuilder() {
    }
    public PointBuilder(Point point) {
        this.x = point.x;
        this.y = point.y;
    }
    public Point toPoint() {
        return new Point(x, y);
    }

    public PointBuilder x(int x) {
        this.x = x;
        return this;
    }
    public PointBuilder y(int y) {
        this.y = y;
        return this;
    }
    public PointBuilder add(Point other) {
        this.x += other.x;
        this.y += other.y;
        return this;
    }
}
Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
2

You cannot do this in Java because there is no operator overloading in Java.

You have to use the second option you have mentioned:

Edit: You can add the Add method in the Point class itself

public Point Add(Point other){
    return new Point(this.x + other.x, this.y + other.y);
}
M S
  • 3,995
  • 3
  • 25
  • 36
  • It seems like it would make more sense to implement an instance method rather than a class method for this. – maček Dec 04 '11 at 12:24
  • 3
    In a mutable class, it would be normal to alter the existing instance, although making `Point` an immutable value would be better. (Also, should be a lower case `a` in `add`.) – Tom Hawtin - tackline Dec 04 '11 at 12:26
2

You cannot overload operators in java. You will need handle this in Point class.

Maxim Manco
  • 1,954
  • 1
  • 12
  • 19
-2

You cannot override operators in Java. That's one of the reasons why any nontrival math (especially geometric) operations should not be implemented in Java (the Point class above is kind of such a class, if you want it to do some real work, for example a line-line intersection, you'd better do it in C++).

Yuhta
  • 168
  • 2
  • 8