歴史的にいくつかの言語(例えば、C++)では、プログラミングにおいて標準の演算子(演算子オーバーロード)をオーバーロードすることが可能であり、ユーザー定義型のデータをより "自然な" 方法で操作できるようにしています。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)"
主なポイント:
equals()とcompareTo()メソッドを使用し、算術演算には自分で定義したメソッドを使用しますJavaで自分のクラスのために==演算子をオーバーロードして、値を比較することは可能ですか?
いいえ、==演算子は常にオブジェクトの参照を比較します。オブジェクトの値を比較するにはequals()をオーバーライドし、論理的等価性が重要なすべての場所でそれを使用する必要があります。
自分のクラスのために"a + b"の動作を実現することはできますか?
通常のメソッドを通じてのみ可能です(たとえば、a.add(b))。C++のような演算子のオーバーロード構文はサポートされていません。
StringはJavaの中で+演算子がオーバーロードされたように振る舞わないのですか?
実際には、+による文字列の連結はString型に対してのみ機能し、コンパイラレベルでサポートされています—これは特定の構文規則です。
==演算子がオブジェクトの値を比較することを期待するa + bのようなコードを書くことを試みる(そのような構文は不可能です)equals()やhashCode()を実装しないことによってコレクションでバグが発生する"点"クラスの開発者が==を使用して2つの点を比較し、座標が一致した場合にtrueを期待する。
長所:
短所:
開発者が点の内容を比較するためにequals()メソッドを実装し、加算にはadd()メソッドを使用する。
長所:
短所: