Исторически в некоторых языках (например, C++), программирование позволяет перегружать стандартные операторы (operator overloading), чтобы сделать пользовательские типы данных более "натуральными" в обращении. В Java на этапе проектирования языка было принято решение операторов не перегружать, чтобы бороться с излишней сложностью и трудночитаемостью кода.
Проблема в том, что иногда действительно удобно было бы определять для своих объектов поведение операторов, например, + для сложения векторов, но это в Java недопустимо на уровне синтаксиса.
Решение — определить обычные методы (например, add, multiply) для работы с объектами либо использовать стандартные подходы: переопределение методов equals() и compareTo() для сравнения; либо применять шаблоны проектирования (например, паттерн "Строитель" или "Композит").
Пример кода:
public class Vector { private int x, y; public Vector(int x, int y) { this.x = x; this.y = y; } public Vector add(Vector other) { return new Vector(this.x + other.x, this.y + other.y); } @Override public String toString() { return "Vector(" + x + ", " + y + ")"; } } Vector v1 = new Vector(1, 2); Vector v2 = new Vector(3, 4); Vector sum = v1.add(v2); // "Vector(4, 6)"
Ключевые особенности:
Можно ли в Java "перегрузить" оператор == для своих классов так, чтобы он сравнивал значения, а не ссылки?
Нет, оператор == всегда сравнивает ссылки для объектов классов. Для сравнения значений объектов нужно переопределять equals() и использовать его везде, где важна логическая эквивалентность.
Можно ли как-то сделать поведение "a + b" для собственных классов?
Только через обычные методы, например, a.add(b). Синтаксис перегрузки операторов, как в C++, не поддерживается.
А разве строки (String) не ведут себя как перегруженный оператор '+' в Java?
На самом деле конкатенация строк при помощи + работает только для типа String, и поддерживается на уровне компилятора — это особое правило синтаксиса.
Разработчик для класса "Точка" использует == для сравнения двух точек и ожидает, что сравнение даст true при совпадающих координатах.
Плюсы:
Минусы:
Разработчик реализует метод equals() для сравнения содержимого точек, а для сложения использует метод add().
Плюсы:
Минусы: