knowledge-kitchen

Object-Orientation - Interfaces (in Java)

As far as the customer is concerned, the interface is the product.

Jef Raskin, initial creator of the Apple Macintosh

  1. Overview
  2. Raison D’Etre
  3. Example
  4. Differences From Classes
  5. Methods With Implementations
  6. Implementing Multiple Interfaces
  7. Polymorphism
  8. Inheritance
  9. Conclusions

Overview

Concept

An interface, like a class, is a Java reference type.

public interface Foo {

  /* some stuff here */

}

Similarity to classes

Like classes, interfaces can contain…

public interface Foo {

  // a property
  public int x = 10;

  // a method
  public static void y() {
    System.out.println("Hello!");
  }

}

False advertising

But all is not as it seems.

Raison d’être

Concept

Interfaces serve as a sort of contract.

Contractual agreement

At their core, interfaces specify a set of method signatures.

Example

A facetious interface

For example, imagine the following interface:

// your mileage may vary
public interface IdealEmployee {
  public abstract void enjoyEatingMealsInCubicle();
  public abstract void rarelyLeaveBuildingOrCampus();
  public abstract void playSillyGamesInOffice();
  public abstract void readilyAcceptAFancyJobTitleInsteadOfIncreasedPay();
}

Any class can “sign on” to this interface using the implements keyword.

public class RecentGrad implements IdealEmployee {
  /* some stuff here */
}

Abiding by the contract

Classes that implement an interface must implement the methods declared within the interface. The code won’t compile otherwise.

public class RecentCollegeGrad implements IdealEmployee {
  public void enjoyEatingMealsInCubicle() {
    // implementation goes here
  }
  public void rarelyLeaveBuildingOrCampus() {
    // implementation goes here
  }
  public void playSillyGamesInOffice() {
    // implementation goes here
  }
  public void readilyAcceptAFancyJobTitleInsteadOfIncreasedPay() {
    // implementation goes here
  }
}

Ensuring consistent behavior across classes

The value of an interface is that it can ensure the same set of behaviors across several different classes.

public class OfficePuppy implements IdealEmployee {
  public void enjoyEatingMealsInCubicle() {
    // implementation goes here
  }
  public void rarelyLeaveBuildingOrCampus() {
    // implementation goes here
  }
  public void playSillyGamesInOffice() {
    // implementation goes here
  }
  public void readilyAcceptAFancyJobTitleInsteadOfIncreasedPay() {
    // implementation goes here
  }
}

Differences from classes

Concept

Unlike classes, interfaces are intended to be abstract and not include implementation details of the behaviors they specify.

Methods With Implementations

Default methods

It is possible to include an instance method with an implementation in an interface. This is called a default method and serves one specific use case, and no other.

public abstract void acceptCutsToCompensationWithNoComplaints();

Default methods (continued)

For example, version 2 of our interface might add the new method, including a default implementation.

public interface IdealEmployee {
  // assume all the methods specified in v1 of the interface are still placed here

  // the new method, with a default implementation so existing class code doesn't break
  public default void acceptCutsToCompensationWithNoComplaints() {
    System.out.println("Thank you so much for giving me this opportunity!");
  }

}

Static methods

Interfaces can also contain implementations of static methods.

public interface IdealEmployee {
  // assume all the methods previously discussed are still placed here

  // a behavior shared by all IdealEmployee objects
  public static void speakDeferrentially(String message) {
    String protocol = "I'm so sorry to disturb you... I know you're very busy... But";
    String output = String.format("%s %s", protocol, message);
  }

}

Implementing Multiple Interfaces

Direct implementation of multiples

Unlike with class-based inheritance, it is possible for a class to implement more than one interface.

public class RecentCollegeGrad implements IdealEmployee, IndependentThinker {

  // all abstract methods from IdealEmployee must be implemented in this class

  // all abstract methods from IndependentThinker must also be implemented in this class

}

Indirect implementation of multiples

Interfaces can also inherit from one-another.

public interface Thinker {
  public abstract void pauseBeforeRespondingToQuestion();
  public abstract void considerAllPossibleImplications(BigEvent bigEvent);
}
public interface IndependentThinker extends Thinker {
  public abstract void lookAskanceTowardsHorizon();
  public abstract void mumbleToOneself();
}

Indirect implementation of multiples (continued)

A class that implements an interface has to implement any abstract methods in the interface, including those passed down from ancestor interfaces.

public class OfficePuppy implements IndependentThinker {

  // must implement all abstract methods from IndependentThinker interface
  public void lookAskanceTowardsHorizon() {
    // implementation goes here
  }
  public void mumbleToOneself() {
    // implementation goes here
  }

  // must also implement all abstract methods from Thinker interface
  public void pauseBeforeRespondingToQuestion() {
    // implementation goes here
  }
  public void considerAllPossibleImplications() {
    // implementation goes here
  }

}

Polymorphism

Concept

Objects that implement a given interface in Java can polymorphically be considered to be of the interface type.

// instantiate an object and reference with variable of interface type
IdealEmployee pat = new RecentCollegeGrade("Pat", 21, "Computer Science");

Batch operations

As with all polymorphism, this can be useful for batch operations.

IdealEmployee[] employees = {
  new RecentCollegeGrade("Pat", 21, "Computer Science"),
  new OfficePuppy("Fido", "German Shepherd", 4)
};
// iterate through each object
for (IdealEmployee emp : employees) {
  emp.acceptCutsToCompensationWithNoComplaints();
}

Conclusions

As you have seen, interfaces in Java offer an alternative form of inheritance in Java with some similarities - and many differences - with class-based inheritance.