In this section, we exhibit three symptoms of Java's over-attachment to objects, starting with an example that implements complex numbers:
public class Complex { private float r, i; public Complex( float a, float b ) { r = a; i = b; } public void negate() { r = -r; i = -i; } public void add( Complex c ) { r = r + c.r; i = i + c.i; } }
The syntax is similar to that of C, with
=
being assignment. Our example defines the class
Complex
, which implements complex numbers: each instance of this
class will represent one complex number.
The definition begins with the line private float r, i;
which declares two private variables, used to hold the real and
imaginary parts.
After this come three methods, Complex
, negate
and
add
. The first of these is a constructor, and would be invoked in
a statement such as
Complex c = new Complex( 3, 4 );It constructs a complex out of two reals by assigning arguments
a
and b
to r
and i
. The second method negates the
number, and the third adds another number to it.
To use this class, one would write, for example:
Complex u = new Complex(2,3); // Declare u and initialise to 2+3i. Complex v = new Complex(5,7); // Declare v and initialise to 5+7i. v.neg(); // Negate v. u.add(v); // Add v to u.
The striking thing about this code is that addition is asymmetric: one
must write u.add(v)
or v.add(u)
, not u+v
.
Java actually has a +
operator that acts on the built-in real and
integer numeric types. However, there is no way to extend it
to user-defined types like Complex
. In Java's philosophy,
all user-defined types are objects, and so the programmer is compelled to
define
this and all other operators as methods. Since any method can be
attached to one and only one object, this means that all binary operators
immediately become asymmetric: a.op(b)
or b.op(a)
. This
is surely unnatural.