One can dismiss the above piece of code by simply saying: it is not object-oriented! To access parts of an object, the classical approach is to use dedicated methods which both access and act on the subobjects. For our running example, we can insert sum methods into each of the classes:
interface List {
int sum();
}
class Nil implements List {
public int sum() {
return 0;
}
}
class Cons implements List {
int head;
List tail;
public int sum() {
return head + tail.sum();
}
}
We can now compute the sum of all components of a given List-object l by writing l.sum(). The advantage of this code is that the type casts and instanceof operations have disappeared, and that the code can be written in a systematic way. The disadvantage is that every time we want to perform a new operation on List-objects, say, compute the product of all integer parts, then new dedicated methods have to be written for all the classes, and the classes must be recompiled.