ti-enxame.com

É possível sobrecarregar operadores em Java?

Eu tenho a seguinte classe, que descreve um ponto na superfície XY:

class Point{
    double x;
    double y;

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

Então, eu quero dominar + e - operadores para ter possibilidade de gravação, execute o seguinte 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)

Como posso fazer isso em Java? Ou devo usar métodos como este:

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

Desde já, obrigado!

20
Dmitry Belaventsev

Você não pode fazer isso em Java. Você precisaria implementar um método plus ou add na sua classe 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)
11
maček

Apesar de você não poder fazê-lo em puro Java, você pode fazê-lo usando plugin do compilador Java-oo . Você precisa escrever método add para o operador +:

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

e o plugin Java-oo apenas desejam os operadores para essas chamadas de método.

7
mart

Não há sobrecarga de operador em Java. Aparentemente, por razões de gosto. Pena mesmo.

(Algumas pessoas alegam que Java tem sobrecarga, por causa de + com String e talvez autoboxing/unboxing.)

Vamos falar sobre os tipos de valor.

Muitas classes iniciais (e algumas posteriores) fazem uma bagunça certa disso. Particularmente no AWT. No AWT, você deve fazer explicitamente cópias de valores simples em todo o lugar. Certamente você deseja tornar imutáveis ​​os tipos de valor - a classe deve ser final e nunca deve mudar de estado (geralmente todos os campos final apontando para imutáveis ​​efetivos).

Assim:

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

O código original estava confuso entre int e double, então eu escolhi um. Se você usou double, deve excluir NaN. "Ponto" tende a implicar um ponto absoluto, que não faz sentido adicionar. "Vetor" ou "dimensão" provavelmente seria mais apropriado, dependendo do que você pretende.

Eu escondi o construtor, pois a identidade não é importante. Possivelmente valores podem ser armazenados em cache. Possivelmente, por exemplo, é comum adicionar um ponto a um ponto zero, portanto, nenhum ponto precisa ser criado.

É possível que você queira uma versão mutável, por exemplo, para usar como acumulador. Essa deve ser uma classe separada sem um relacionamento de herança. Provavelmente não em casos simples, mas mostrarei de qualquer maneira:

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
Tom Hawtin - tackline

Você não pode sobrecarregar operadores em Java. Você precisará lidar com isso na classe Point.

2
Maxim Manco

Você não pode fazer isso em Java porque não há sobrecarga de operador em Java.

Você precisa usar a segunda opção que você mencionou:

Editar: você pode adicionar o método Add na própria classe Point

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