Our first two symptoms --- the asymmetry of binary
operators, and the surprising behaviour of equality --- have now been
explained. What about the third: that sin
is not
a method of class Float
, but attached (as a static method) to
a completely different class, Math
?
The reason is efficiency. In principle, OOP languages with inheritance
allow one to define subclasses of any class. This would mean that even
though the basic Java implementation of real numbers doesn't provide a
sin
method, anyone who wants to implement a maths library could
define a subclass of Float
, and equip it with some extra methods:
public class MathFloat is Float { public float sin () { ... } }
However, although Java permits user-defined classes to be subclassed, for efficiency, it doesn't permit this of built-in types. Instead, the library implementors have abused the existing language facilities to define a module of basic mathematical functions. In the words of Lemay and Perkins [Lemay and Perkins]
Class methods can also be useful for gathering general methods together in one place (the class). For example, theMath
class defined in thejava.lang
package, contains a large set of math operations as class metumbers in Java are not normally represented as objects. The constant 2.0 is an instance of the typefloat
, which is one of several built-in non-object types. These are the only possible non-object types: users are not allowed to create their own.To parallel these, Java provides a range of built-in object types. (The naming conventions are such that the non-object types start with a lower-case letter; all object types with an upper-case letter.) It is easy to convert from non-objects to objects:
float x = 1.2; Float X = new Float( x );Here, the first variable is a number of the built-in typefloat
, and the second is an object of the built-in typeFloat
. The right-hand-side of the second assignment calls the constructor method for typeFloat
, passing it a number as argument and returning the corresponding object.Knowing how easy it is to convert numbers to objects, we might expect that Java would implement
sin
,cos
, and other methods --- there are no instances of the classMath
, but you can still use its methods with numbers or boolean arguments.
Given that numbers should not be implemented as objects, and that therefore they should not have methods, we believe that Java needs a proper module construct for such situations. It is worth pointing out that while several OOP languages try to fudge modules by implementing them with classes and static methods, some earlier languages have done the reverse, trying to implement objects as modules. There is a frequent confusion between the two in OOP, and we shall discuss this in a future paper.