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!

0

6 Answers 6

19

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)
Sign up to request clarification or add additional context in comments.

3 Comments

In a mutable class, it would be normal to alter the existing instance, although making Point an immutable value would be better.
@TomHawtin-tackline made edits based on your comment.
another reason to hate Java :(
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.

1 Comment

and of course this is a stupid idea unless it's only you who would ever read your code
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;
    }
}

Comments

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);
}

2 Comments

It seems like it would make more sense to implement an instance method rather than a class method for this.
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.)
2

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

2 Comments

That's, um, a surprising constructor. Sure you wouldn't, say, want to make it a static method with a name, such as sum?
Well, there is a lot of ways to do it. The bottom line here that you can't override operators.
-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++).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.