Previous Contents Next

Object-oriented languages: comparison with Java

Although Objective CAML sprang from the functional world, it is necessary to compare its object-oriented extension to an important representative of the object-oriented languages. We pick the Java language which, while similar from the point of view of its implementation, differs strongly in its object model and its type system.

The Java language is an object-oriented language developed by the SUN corporation. The main site for access to the language is the following:


Main characteristics

The Java language is a language with classes. Inheritance is simple and allows redefinition or overloading of inherited methods. Typing is static. An inherited class is in a subtyping relationship with its ancestor class.

Java does not have parameterized classes. One gets two types of polymorphism: ad hoc by overloading, and of inclusion by redefinition.

It is multi-threading and supports the development of distributed application whether using sockets or by invoking methods of remote objects (Remote Method Invocation).

The principles of its implementation are close to those of Objective CAML. A Java program is compiled to a virtual machine (JVM). The loading of code is dynamic. The code produced is independent of machine architectures, being interpreted by a virtual machine. The basic datatypes are specified in such a way as to guarantee the same representation on all architectures. The runtime is equipped with a GC.

Java has important class libraries (around 600 with the JDK, which are supplemented by many independent developments). The main libraries concern graphical interfaces and I/O operations integrating communication between machines.

Differences with Objective CAML

The main differences between Java and Objective CAML come from their type system, from redefinition and from overloading of methods. Redefinition of an inherited method must use parameters of exactly the same type. Method overloading supports switching the method to use according to the types of the method call parameters. In the following example class B inherits from class A. Class B redefines the first version of the to_string method, but overloads the second version. Moreover the eq method is overloaded since the type of the parameter (here B) is not equal to the type of the parameter of the inherited method (here A). In the end class B has two eq methods and two to_string methods.
class A {
  boolean eq (A o) {  return true;}
  String to_string (int n ) { }

class B extends A {
  boolean eq (B o) {  return true;}
  String to_string (int n ) { }
  String to_string (float x, float y)
Although binding is late, overload resolution, that is determination of the type of the method to use, is carried out on compilation.

The second important difference derives from the possibility of casting the type of an object, as would be done in C. In the following example, two objects a and b are defined, of class A and B respectively. Then three variables c, d and e are declared while imposing a type constraint on the affected values.
  A a = new A ();
  B b = new B ();
  A c = (A) b;
  B d = (B) c;
  B e = (B) a;
Since the type of b is a subtype of the type of a, the cast from b to c is accepted. In this case the type constraint may be omitted. On the other hand the two following constraints require a dynamic type test to be carried out to guarantee that the values in c and in a do in fact correspond to objects of class B. In this program this is true for c, but false for a. So this last case raises an exception. While this is useful, in particular for graphical interfaces, these type constraints can lead to exceptions being raised during exception due to erroneous use of types. In this Java is a language typed partly statically and partly dynamically. Moreover the absence of parameterized classes quite often obliges one to use this feature to write generic classes.

Previous Contents Next