By Doug Lowe

Although interfaces are an incredibly useful feature of Java, they have an inherent limitation: After you define an interface and then build classes that implement the interface, there’s no easy way to modify the interface by adding additional methods to it.

For example, suppose you have created the following interface:

public interface Playable
{
 void play();
}

You then build several classes that implement this interface. Here’s a simple example:

class Game implements Playable
{
 public void play()
 {
  System.out.println("Good luck!");
 }
}

This is a pretty pointless game, of course; it simply prints the message “Good luck!” whenever the play method is called.

Now suppose that you decide that the Playable interface should have an additional features — specifically, you want to add the ability to end the game by calling a method named quit.

You’d be tempted to just add the new method to the existing interface, like this:

public interface Playable
{
 void play();
 void quit();
}

Unfortunately, however, doing so will break the Game class because it doesn’t provide an implementation of the quit method.

You could, of course, modify the Game class by adding an implementation of the quit method. But what if you have written dozens, or even hundreds, of classes that implement Playable? As you can imagine, once an interface has become popular, it becomes nearly impossible to modify.

To alleviate this problem, Java 1.8 introduces a new type of interface method called a default method, which supplies code that will be used as the implementation of the method for any classes that implement the interface but do not themselves provide an implementation for the default method.

Thus, Java 8 allows you to safely add the quit method to the Playable interface by specifying it as a default method, like this:

interface Playable
{
    void play();
    default void quit()
    {
        System.out.println("Sorry, quitting is not allowed.");
    }
}

Here the Playable interface specifies that if an implementing class does not provide an implementation of the quit method, the default method will be used. In this case, the default method simply prints the message “Sorry, quitting is not allowed.”

Note that the preceding example won’t compile on versions of Java prior to 1.8. If you get an error message when you try to compile an interface that uses the default keyword, check your Java version to make sure you’re running version 1.8 or later.

Here’s a complete example that uses the Playable interface and its default method:

public class TestLambdaCollection
{
 public static void main(String[] args)
 {
  Game g = new Game();
  g.play();
  g.quit();
 }
}
interface Playable
{
 void play();
 default void quit()
 {
  System.out.println("Sorry, quitting is not allowed.");
 }
}
class Game implements Playable
{
 public void play()
 {
  System.out.println("Good luck!");
 }
}

When you run this program, the following will be displayed on the console:

Good luck!
Sorry, quitting is not allowed.