2011-12-04 13 views
9

he la clase siguiente, que describe un punto en XY superficie:¿Es posible anular operadores en Java?

class Point{ 
    double x; 
    double y; 

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

Así que quiero para alterar "+" y "-" a los operadores tienen plazo de escritura posibilidad siguiente código:

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) 

¿Cómo puedo hacerlo en Java? O debería utilizar métodos como este:

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

TIA!

Respuesta

2

No se puede hacer esto en Java porque no hay sobrecarga del operador en Java.

usted tiene que utilizar la segunda opción que usted ha mencionado:

Editar: Puedes añadir el método Add en la propia clase Point

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

Parece que tendría más sentido implementar un método de instancia en lugar de un método de clase para esto. –

+2

En una clase mutable, sería normal alterar la instancia existente, aunque hacer 'Punto' un valor inmutable sería mejor. (Además, debería ser una minúscula 'a' en' add'.) –

8

No se puede hacer esto en Java. Tendría que implementar un método plus o add en su clase 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; 
    } 
} 

uso

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) 
+0

En una clase mutable, sería normal modificar la instancia existente, aunque hacer 'Punto' un valor inmutable sería mejor. –

+0

@ TomHawtin-tackline realizó ediciones basadas en su comentario. –

2

No se puede sobrecargar los operadores en Java. Necesitará manejar esto en la clase Point.

+0

Eso es, um, un sorprendente constructor. Claro que no quiere, por ejemplo, querer hacer que sea un método estático con un nombre, como 'sum'? –

+0

Bueno, hay muchas formas de hacerlo. La conclusión aquí es que no puede anular operadores. –

1

No hay sobrecarga del operador en Java. Aparentemente por razones de gusto. Lástima realmente.

(Algunas personas afirman que Java tiene sobrecarga, debido + con String y quizás autoboxing/unboxing.)

Vamos a hablar de los tipos de valor.

Muchas clases tempranas (y algunas posteriores) hacen un lío perfecto de esto. Particularmente en AWT. En AWT debería hacer copias explícitas de valores simples en cualquier lugar. Es casi seguro que desee que los tipos de valor sean inmutables: la clase debe ser definitiva y nunca debe cambiar de estado (generalmente todos los campos final apuntan a inmutables efectivos).

Así:

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

El código original estaba confundido entre int y double, por lo que he elegido uno. Si usó double, debe excluir NaN. "Punto" tiende a implicar un punto absoluto, que no tiene sentido agregar. "Vector" o "dimensión" probablemente serían más apropiados, dependiendo de lo que pretendas.

He ocultado el constructor, ya que la identidad no es importante. Posiblemente los valores podrían almacenarse en caché. Posiblemente es, por ejemplo, común agregar un punto a un punto cero, por lo que no es necesario crear puntos.

Es posible que desee una versión mutable, por ejemplo, para usar como acumulador. Esta debe ser una clase separada sin una relación de herencia.Probablemente no en casos sencillos, pero voy a mostrar todas formas:

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

A pesar de que no puede hacerlo en Java puro que puede hacerlo utilizando java-oo compiler plugin. Usted tiene que escribir método para añadir operador +:

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

y el plugin de java-oo operadores simplemente desugar a estas llamadas a métodos.

-1

No puede anular operadores en Java. Esa es una de las razones por las cuales las operaciones matemáticas no restrictivas (especialmente las geométricas) no deben implementarse en Java (la clase anterior Point es una de esas clases, si quieres que haga un trabajo real, por ejemplo, una intersección de línea-línea, será mejor que lo hagas en C++).

Cuestiones relacionadas