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
- Overview
- Raison D’Etre
- Example
- Differences From Classes
- Methods With Implementations
- Implementing Multiple Interfaces
- Polymorphism
- Inheritance
- 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…
-
properties
-
methods
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.
-
Interfaces are intended to solve a very different problem than classes.
-
Because of their intended use, there are very specific limitations on what kinds of properties and methods can be placed within an interface.
Raison d’être
Concept
Interfaces serve as a sort of contract.
-
An interfaces defines a public interface - a set of behaviors - that any class can agree to adhere to.
-
Java will not compile the code if any class that agreed to adhere to an interface does not properly implement its public interface.
Contractual agreement
At their core, interfaces specify a set of method signatures.
-
Any class can declare that it implements an interface, meaning it agrees to implement the behaviors the interface specifies.
-
This contractually guarantees that the class will implement the methods specified in the interface.
-
Other code can rely on the fact that the class will be able to perform the behaviors the interface specifies.
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
}
}
- The class may contain other properties and methods in addition to those specified in the interface.
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
}
}
- The expectation would be that the implementation of these behaviors is significantly different among the different classes that implement them.
Differences from classes
Concept
Unlike classes, interfaces are intended to be abstract and not include implementation details of the behaviors they specify.
-
all methods are abstract by default, even if that is not written explicitly into the code.
-
all properties and methods in an interface are public, even if that is not written explicitly into the code.
-
all properties are furthermore static and constant, even if that is not written explicitly into the code.
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.
-
Imagine our example interface is already in use - developers have writen code abiding by its contractual rules.
-
Now, imagine the creators of the interface decide to add a new abstract method
public abstract void acceptCutsToCompensationWithNoComplaints();
-
If the developers using the old interface upgraded to the new version, their code would immediately break and not compile.
-
A default method solves this problem by including a new method in an interface that includes its own default implementation - a placeholder until the developers can write their own.
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!");
}
}
- In this way, developers using
v1
of the interface can upgrade tov2
with no worry about their code breaking.
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.
-
Imagine we had a second interface called
IndependentThinker
. -
A single class could implement both the
IdealEmployee
andIndependentThinker
interfaces.
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.
- For example, let’s imagine a simple parent interface:
public interface Thinker {
public abstract void pauseBeforeRespondingToQuestion();
public abstract void considerAllPossibleImplications(BigEvent bigEvent);
}
- And a child interface:
public interface IndependentThinker extends Thinker {
public abstract void lookAskanceTowardsHorizon();
public abstract void mumbleToOneself();
}
- As with class-based inheritance, a child interface inherits all the methods and properties of the parent, including abstract methods.
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.
- For example, a
RecentCollegeGrad
object could be referenced by aIdealEmployee
-typed variable.
// 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.
- Create an array data structure with a bunch of objects that all implement the interface
IdealEmployee[] employees = {
new RecentCollegeGrade("Pat", 21, "Computer Science"),
new OfficePuppy("Fido", "German Shepherd", 4)
};
- Loop through them and trigger some behaviors they all have in common.
// 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.
- Thank you. Bye.