651.288.7000 info@intertech.com

I’ve been programming in Java for over 16 years and teaching it for nearly half that time. So it’s going to take a little practice to stop repeating this sentence: “Interfaces may only contain methods that are public and abstract.”  As of Java 8, that statement is no longer true.  It is now possible to add both instance and static methods to Java interfaces.

Review: The Contract

When a class declares that it implements an interface, it must implement all of the abstract methods contained in that interface’s hierarchy OR the class must be declared abstract itself.  For example, if I have the following interface…

… and create the following class…

I’ll receive the following error: “The type MidwestCustomerService must implement the inherited abstract method CustomerService.setCustomer(Customer).”  By adding the missing setCustomer method the error goes away. Interfaces 101, right?

So imagine a situation where you have a interface that is used by numerous implementing classes, yet you’d like to give it one or more additional methods.  What are your options (in Java 7 and earlier)?

  • Add the method, forcing all implementing classes to include the new methods once they’ve upgraded to the latest and greatest interface.
    • Pros: If you really think all implementing classes must include these new methods, adding the methods to the interface will definitely enforce this requirement (unless they don’t upgrade to your latest version).
    • Cons:  How many implementations of your interface exist?  Are these methods truly important enough to warrant forcing everyone else to update their code?
  • Move the code from an interface to an abstract class, adding default implementations of the new methods.
    • Pros: Those that want to override the methods can, and those that don’t aren’t required to do so.
    • Cons:  Everyone has to change their code to extend the abstract class.  In some cases, due to Java’s single inheritance rule, this may be impossible to do without time consuming refactoring/rewriting.
  • Extend the original interface with a new interface.
    • Pros: Those that want to add the new functionality can, and those that don’t aren’t required to do so.
    • Cons: Those that want to include the new methods will have to rewrite all of their existing interface references.  Likewise, if we want these methods to be available to all clients in a specific version of our application, we’ll need to make sure all references are rewritten with this new extended interface.

As of Java 8, we now have another option: default methods!

Default Methods

A default method resembles an instance method (though without access to any instance variables) that has been added to an interface.  That’s right – a method with a body.  Much like an abstract class or extended interface, this allows, but doesn’t force, someone to implement the new interface methods.  Unlike those two, there is no need to rewrite all of your type references (e.g. from the old interface type to the new abstract class or extended interface type) to take advantage of the new methods.

All that is needed to create a default method is the “default” modifier.

Now classes can choose to override this method, or just ignore it (without the error we saw in the first example).  Both of the following examples are “legal” implementations of the CustomerService interface:

 

 

Static Methods

In addition to adding instance methods to an interface, we are also able to add static methods.  The syntax is similar… we just use the “static” modifier in the method signature and include a method body.

While you may add a method with the same signature in an implementing class, you’re not truly overriding the static interface method.  In other words, the static method can only be called through the interface or class type reference, not an instance variable:

 

 

Abstract Classes vs Default/Static Methods

Is this starting to sound a lot like an abstract class?  Well, they’re similar, but remember, an abstract class may contain mutable state (instance variables), whereas an interface may only define behavior and constants.  In addition, a class may only directly inherit from one class, but may implement as many interfaces as required.  If you require mutable state, and you are certain that a class would make a reasonable subclass, you’ll want to consider an abstract class.  In other cases, consider using an interface with default/static methods.

Like What You've Read?

Subscribe to the Blog.

Every Friday we send that week's content from our Developers via email. Try it out!

Some ad blockers can block the form below.

You have Successfully Subscribed!

Pin It on Pinterest

Share This