A second basic question: When you user 'super.f()', will Java go up the calling chain until it finds method 'f' (and report an err if none is found) or does it expect to find 'f' immediately at its very first parent?
Objects of that class are also objects of whatever type the class is named, and they are also objects of the Object type because everything ultimately extends Object. So in that case they have at least three different types which they can be applied to. There's no difference between Object and Comparable in this case; the class extends Object and implements Comparable but from the type point of view it doesn't matter whether the types are inherited or implemented.
Lets say we are engineering a new electronic device called a star-blaster... this device is used to save the world from incoming stars with the potential of crashing into Earth.
How will the user of this device interact with it? What is the interface?
We say that the user needs to enter some values stating the co-ordinates and distance then confirm using a button to initialize the laser beam... this abstract idea becomes the interface for any model of a star-blaster so we create it...
Application code for the interface
Now we create two distinct models using this interface...
Application code to control the first model:
Application code to control the second model:
During development we decide that we can configure the models in such a way that one can be selected to fire off based on the star size due to the power difference of the laser beam in the both... to achieve such a requirement you have to program the configuration to an interface and not a specific implementation as follows...
From this you see that we can choose an implementation at runtime causing dynamic behaviour....
The main point is an interface allows your code to be flexible in that a reference to an interface allows you to refer to any object implementing it without the objects belonging to the same family, whereas using a reference to specific type only allows you to reference objects of that specific type...
To create a system that is flexible
Dan Bromberg wrote:I'm looking for a heuristic explanation of how to think of an "interface" as a type.
I'm not sure that "heuristic" is the right term, but in most OO languages a type defines what something can do; and that's what interfaces are all about. They define methods, not implmentations.
Therefore, if I hand a class/method a List (java.util.List), I - and the method/class that gets it - knows that the object will have certain methods that operate in documented ways.
One possible way to think about is like a Car. I don't have to know how an internal combustion engine works, but I know that when I get into the drivers seat, there will be two or three pedals, a steering wheel, a gear shift, hopefully some mirrors, and an ignition key or starter. And if I get in any car, anywhere around the world, made by any manufacturer, I won't have to read a new manual to work out how to drive it. In programming terms, that makes a Car a type.
Dan Bromberg wrote:I'm looking for a heuristic explanation of how to think of an "interface" as a type. I'm used to think of the 'type' of a class coming form its very definition but I often see casting to an interface which I still feel very uncomfortable about. I've never read a decent explanation as to why it makes sense to do so. Other than an interface, are there other unusual ways a 'type' may be referred to?
What makes a class a type (in Java)? The interface. The implementation can change, either by language features (in Java inheritance) or by patterns (composition, aggregation, strategy pattern...). Or it doesn't even exist, in abstract classes. An abstract class with methods only is still a class but basically not different from an interface in its distinct features (i.e. everything that differs from its superclass), it just restricts the inheritance to a fixed super type. A class is a type because it has an interface mangled into it. (My interpretation.) It is not the interface that is "unusually" extracted from some class. Some languages don't have the distinction between classes and interfaces. In Java it is quite important because interfaces allow multiple inheritance while classes do not.
In fact some frameworks heavily utilize this approach to reduce complexity and to decouple implementation and interface. When testing, working with Spring or Java EE you barely work with classes but mostly with interfaces. Most of the time you don't even know the specific class that is used at runtime. You still have the types that define what you can do with the objects.
Thinking of classes as the main or basic types often derives from learning them first when learning Java. But you somehow need to unlearn this. It was a simplification for learning the basics. It is less than helpful when diving deeper in. "coming from its very definition" is wrong (at least for Java), the definition of a class is not that a type is a class; a class is a type ("A class declaration specifies a new named reference type." - JLS), but it is not the only type and the definition of type is not "a class".
See the JLS:
* http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.6 Types, classes, and interfaces
* http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html Interfaces: "An interface declaration introduces a new reference type..."
Dan Bromberg wrote:A second basic question: When you user 'super.f()', will Java go up the calling chain until it finds method 'f' (and report an err if none is found) or does it expect to find 'f' immediately at its very first parent?
Java will not report an error if the method is not found because by the type of variable the compiler knows that such a method has to exist somewhere in the hierarchy. You couldn't compile the code if it wouldn't exist. It then uses the first implementation in the parent hierarchy.