Interfaces

What is an Interface?

An interface is a class-like construct that contains only constants and abstract methods. In many ways, it is similar to an abstract class -- but it instead aims to specify the behavior of a class that implements it. Of course, a class can have many different behaviors associated with it, so a class might implement several interfaces. For example, we might want to ensure that objects of a particular class are comparable, edible, cloneable, etc... and could do this by having the class implement interfaces Comparable, Edible, Cloneable, etc...

For a class to implement an interface it must implement all of the abstract methods specified in that interface.

Like an abstract class, you cannot create an instance from an interface using the new operator, however you can:

Defining an Interface

The following syntax should be used to define an interface:

public interface InterfaceName {
   constant declarations;
   method signatures;

Here's an example:

public interface Edible {
    //every class that claims to be "edible"
    //must be able to describe how they can be eaten...
    public abstract String howToEat();
}

Omitting Modifiers in Interfaces

All data fields in an interface are automatically public final static (i.e., constants), and all methods in an interface must public abstract. As such, explicitly including these modifiers in the interface definition is not necessary.

Consequently,

public interface T1 {
   public static final int K = 1;
   public abstract void p();
}

is the same as...

public interface T1 {
   int K = 1;
   void p();
}

Once an interface has been defined, you still need to have some class implement it. Again, classes are not limited to implementing just one interface. As an example, consider the following two interfaces:

public interface Predator {
    boolean chasePrey(Prey p);
    void killPrey(Prey p);
}
public interface Prey {
   void fightFleeOrGetEaten();  //actions taken (or not taken) when 
                                //under the threat of a predator
}

and here two classes that implement one or both of the above:

public class Lion implements Predator {

   public boolean chasePrey(Prey p) {
        return (isWorthEating(p) && this.hungry) 
   }

   public void killPrey(Prey p) {
        useClaws(p);
        while ( ! Dead(p) ) 
             bite(p);
   }

   ...

}
public class Frog implements Predator, Prey {

  public boolean chasePrey(Prey p) {
      return (isBug(p) && isOneToungeLengthAway(p))
  }

  public void killPrey(Prey p) {
      useStickyTongue(p);
      swallow(p);
  }

  public void fightFleeOrGetEaten() {
      tryJumpingAway();
      trySwimmingAway();
  }

  ...

}

As can be seen above, classes may implement multiple interfaces. However, one must take care that there are no conflicting elements in those interfaces (e.g., two constants with the same name but different values, or two methods with the same signature, but different return types. Fortunately, such errors are detected by the compiler.

The Comparable Interface

One very useful interface to implement is the "Comparable" interface. This interface is defined in the java.lang package:

public interface Comparable {
   public int compareTo(Object o);
}

Many classes (e.g., String and Date) in the Java library implement Comparable to define a natural order for the objects they define. For example, Strings can be compared lexicographically (i.e., which String would "come first" alphabetically) with the String.compareTo() method. Similarly, one can determine which of two dates "comes first" by appealing to the Date.compareTo() method.

Interfaces vs. Abstract Classes

While somewhat similar, there are distinct differences between interfaces and abstract classes. For example:

The following table displays some of the major differences:

  Variables Constructors Methods
Abstract Class No restrictions Constructors are invoked by subclasses through constructor chaining, even though an abstract class can't be instantiated using the new operator. No restrictions
Interface All variables must be public static final No constructors. An interface cannot be instantiated using the new operator All methods must be public abstract instance methods

Also, all classes share a single root, the Object class, but there is no single root for interfaces.