An interface is a way to specify which methods a class supports without specifying implementations of those methods. Think of an interface as a list of requirements. It doesn't specify how things should be done, but it specifies what must be done. It forms a contract: any class that implements an interface agrees to abide by the terms of the contract.
Interfaces are introduced to the JVM using the same class file format used for classes. To create an interface using Oolong, suppose you wish to create an interface Amiable, which says that anything which is amiable must be able to smile and be able to shake hands with somebody else who is amiable. The Oolong definition is
.interface Amiable .method public abstract smile ()V ; No implementation; there is no code here .end method .method public abstract shakeHands(LAmiable;)V ; No implementation; there is no code here .end method
The methods are all marked with the abstract keyword, because no implementations are provided. This is a requirement in the JVM specification.
Interfaces are used with the .implements directive. If a class implements an interface, then it should provide implementations (that is, non-abstract methods) for all the methods in the interface. If any method that is declared in the interface isn't defined in the class, then that class itself must be declared abstract to prevent it from being instantiated.
Here is some code that defines a friendly person. A friendly person is a Person who implements the Amiable interface.
.class FriendlyPerson .super Person .implements Amiable ; Implementation of the smile method .method public smile ()V ;; Implementation of smile omitted .end method .method public shakeHands (LAmiable;)V ;; Implementation of shakeHands omitted .end method
Unlike the .super directive, there may be more than one .implements directive in a class. There can be at most one .super directive. If there isn't one, the Oolong assembler assumes that the superclass is java/lang/Object.
The reason you have exactly one superclass but any number of interfaces has to do with difficulties with multiple inheritance. Multiple inheritance can be hard, because it's easy for names of methods to conflict between the various superclasses. If you inherit two method definitions from two different superclasses, it becomes hard to tell which method implementation you should use. This isn't a problem with interfaces, because there is only one definition of each method; it doesn't inherit any implementations.
You have to have one superclass because that ensures that everything can be treated identically as an Object. For example, the Vector class in java.util can be used to store any object, because each object has Object as a superclass somewhere in its inheritance tree.
Interfaces may also implement other interfaces:
.interface Clever .method public abstract solvePuzzles()V .end method .end class .interface JavaProgrammer .implements Amiable .implements Clever .method public abstract writeJavaPrograms()V .end method .end class
A JavaProgrammer is able to do all the methods in Amiable, all the methods in Clever, and the method writeJavaPrograms. This means that a Java programmer must be able to smile, shake hands, and be able to solve puzzles as well as write Jave programs to be considered a real Java programmer by the JVM.
In this case the directive .implements is a little misleading, because an interface doesn't really implement anything. The JavaProgrammer interface doesn't specify how to implement the methods in Amiable; it just specifies that they must be implemented by any class implementing JavaProgrammer. If an interface implements other interfaces, then it inherits the requirement to implement all of the methods in all interfaces.
The .interface directive is equivalent to using the .class directive with the interface keyword. For example,
.interface public java/util/Enumerator
is equivalent to
.class interface abstract public java/util/Enumerator