是否有可能在Java中重载运算符?
我有以下类,它描述了XY表面上的一个点:
class Point{ double x; double y; public Point(int x, int y){ this.x = x; this.y = y; } }
所以我想overlad +
和-
运算符有可能写代码运行:
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); }
提前致谢!
你不能用Java做到这一点。 您必须在Point
类中实现plus
或add
方法。
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 // eg, a.add(b).add(c)
尽管你不能在纯java中做到这一点,你可以使用java-oo编译器插件来做到这一点。 你需要为+运算符编写add方法:
public Point add(Point other){ return new Point(this.x + other.x, this.y + other.y); }
和java-oo插件只是desugar运算符这些方法调用。
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+")"; } }
原始代码在int
和double
之间混淆,所以我选择了一个。 如果您使用double
,则应排除NaN
。 “点”倾向于暗示一个绝对点,添加没有意义。 “矢量”或“尺寸”可能更合适,具体取决于您的意图。
我隐藏了构造函数,因为身份并不重要。 可能会缓存值。 例如,将点添加到零点可能是常见的,因此不需要创建点。
您可能想要一个可变版本,例如用作累加器。 这应该是一个没有inheritance关系的单独类。 可能不是在简单的情况下,但无论如何我会展示它:
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; } }
您无法在Java中执行此操作,因为Java中没有运算符重载。
你必须使用你提到的第二个选项:
编辑:您可以在Point类本身中Add
方法
public Point Add(Point other){ return new Point(this.x + other.x, this.y + other.y); }
你不能在java中重载运算符。 您需要在Point
类中处理此问题。
您无法在Java中覆盖运算符。 这就是为什么任何非竞争性数学(尤其是几何)操作都不应该用Java实现的原因之一(上面的Point
类就是这样一个类,如果你想让它做一些真正的工作,例如一个线 – 线交点,你最好用C ++做这件事。