我有以下类,描述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);
}
提前致谢!
答案 0 :(得分:11)
你不能用Java做到这一点。您必须在plus
课程中实施add
或Point
方法。
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+")";
}
}
原始代码在int
和double
之间混淆了,所以我选择了一个。如果您使用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 ++做。)