store(file:FILE) {...}
,
Storable retrieved(file:FILE) {...}
, etc.
In Java, such functionality can be achieved in many cases without
taking recourse to multiple inheritance, as discussed below.
The general purpose methods can be housed in the root class and made available only when a client implements a suitable interface. For instance, the clone()-method is defined in class java.lang.Object as protected and is inherited by all classes. However invoking it on an arbitrary object can cause CloneNotSupportedException to be thrown. To run the clone()-method on an instance of a class, the class must implement the ``marker'' interface Cloneable and redefine clone().
Java classes such as java.io.ObjectInputStream and java.io.ObjectOutputStream support readObject(obj)
and
writeObject(obj)
respectively to read from / write to a
persistent storage. Java also requires a class to implement the
``marker'' interface Serializable before it can participate in
these methods. Observe that the signatures of these methods are
``inverted'' when compared with the corresponding methods of class
Storable in Eiffel.
Cloning and storing objects are the only examples that cannot be regarded as instances of our translation. The cloning mechanism is hardwired in a native method of class Object; the serialisation mechanism makes heavy use of reflection in order to determine whether the implementor of the Serializable interface provides its own writeObject() method. In fact both make better examples of functionality that cannot be modeled in a way that is recommendable as an idiom.