是否有可能在Java中重载运算符?

时间:2011-12-04 12:18:17

标签: java operator-overloading

我有以下类,描述XY表面上的一个点:

class Point{
    double x;
    double y;

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

所以我想要覆盖+-运算符,以便有可能在代码后运行:

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)

我怎样才能用Java做到这一点?或者我应该使用这样的方法:

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

提前致谢!

6 个答案:

答案 0 :(得分:11)

你不能用Java做到这一点。您必须在plus课程中实施addPoint方法。

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

使用

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)

答案 1 :(得分:7)

尽管您无法在纯Java中执行此操作,但您可以使用java-oo compiler plugin执行此操作。 您需要为+ operator:

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

和java-oo插件只是desugar运算符到这些方法调用。

答案 2 :(得分:3)

Java中没有运算符重载。显然出于口味的原因。真可惜。

(有些人会声称Java确实有重载,因为+带有String并且可能是自动装箱/拆箱。)

让我们谈谈价值类型。

许多早期课程(以及一些后期课程)都是如此。特别是在AWT。在AWT中,您应该明确地在整个地方制作简单值的副本。几乎可以肯定你想让值类型成为不可变的 - 类应该是final,它应该永远不会改变状态(通常所有final字段都指向有效的不可变量。)

所以:

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

原始代码在intdouble之间混淆了,所以我选择了一个。如果您使用double,则应排除NaN。 “点”倾向于暗示一个绝对点,添加没有意义。 “矢量”或“维度”可能更合适,具体取决于您的意图。

我隐藏了构造函数,因为身份并不重要。可能会缓存值。例如,将点添加到零点可能是常见的,因此不需要创建点。

您可能想要一个可变版本,例如用作累加器。这应该是一个没有继承关系的单独类。可能不是在简单的情况下,但无论如何我都会展示它:

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

答案 3 :(得分:2)

您无法在Java中执行此操作,因为Java中没有运算符重载。

您必须使用您提到的第二个选项:

编辑:您可以在Point类本身中添加Add方法

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

答案 4 :(得分:2)

你不能在java中重载运算符。您需要在Point课程中处理此问题。

答案 5 :(得分:-2)

您不能在Java中覆盖运算符。这就是为什么任何非竞争性数学(特别是几何)操作不应该用Java实现的原因之一(上面的Point类就是这样一个类,如果你想让它做一些真正的工作,例如一行-line intersection,你最好用C ++做。)

相关问题