We’ve talked about Classes, and we’ve also talked briefly about the concept of Abstraction in our post on Functions. Now I think its time that we talk about Interfaces in Java, which allow us to apply the concept of Abstraction to classes. An Interface is structured similarly to a Class, however the Interface will only include the declarations. The implementation of any methods will occur later.
What might this look like? Let’s return to our Ice Cream example from our post on Classes. We had the following snippet of code for interacting with our Ice Cream.
IceCream iceCream = new IceCream("Chocolate Marshmallow", 3);
while (iceCream.getScoops() > 0) {
iceCream.eatScoop();
System.out.println("Yum! I had a scoop of " + iceCream.getFlavor() + " ice cream.");
}
System.out.println("All out of " + iceCream.getFlavor() + " ice cream :(");
What if we wanted to represent more types of desserts than just Ice Cream? We could create a Dessert Interface which would define the methods that we would need from a Dessert.
public interface Dessert {
public String getFlavor();
public String getName();
public int getAmount();
public void add(int amountToAdd);
public void eat();
}
Again, this is only including the declarations of our methods, and we will leave the attributes to our implementing classes.
We could then rewrite our Ice Cream class to implement our Dessert interface
public class IceCream implements Dessert {
protected String flavor;
protected int scoops;
public IceCream(String flavorParameter, int scoopsParameter) {
flavor = flavorParameter;
scoops = scoopsParameter;
}
public IceCream(String flavorParameter) {
flavor = flavorParameter;
scoops = 0;
}
@Override
public String getFlavor() {
return flavor;
}
@Override
public String getName() {
return flavor + " ice cream";
}
@Override
public int getAmount() {
return scoops;
}
@Override
public void add(int amountToAdd) {
scoops += amountToAdd;
}
@Override
public void eat() {
scoops--;
}
}
We are providing the implementations for the five methods specified in the Dessert interface. Also we have the “Override” annotation to indicate that our Ice Cream method implementations are overriding, or in this case implementing, the methods from the interface.
To provide some contrast, let’s add another Dessert that can implement our interface. How about some pie?
public class Pie implements Dessert {
protected String flavor;
protected int slices;
public Pie(String flavorParameter, int slicesParameter) {
flavor = flavorParameter;
slices = slicesParameter;
}
@Override
public String getFlavor() {
return flavor;
}
@Override
public String getName() {
return flavor + " pie";
}
@Override
public int getAmount() {
return slices;
}
@Override
public void add(int amountToAdd) {
slices += amountToAdd;
}
@Override
public void eat() {
slices--;
}
}
Again, we are implementing the five methods in our Dessert but in some cases things differ. For example, tracking the “amount” of dessert Ice Cream is measured in scoops and Pie is measured in slices so we have different underlying attributes. The “name” of our dessert will differ based on what type of dessert it is, so our Ice Cream and Pie classes will return slightly different values rather than just their flavor.
Then, we could rewrite our snippet of code from above to use the Dessert interface so that it could work with any class implementing our Dessert interface.
Dessert iceCream = new IceCream("Chocolate Peanut Butter", 3);
Dessert pie = new Pie("Banana Cream", 2);
List<Dessert> desserts = new ArrayList<>();
desserts.add(iceCream);
desserts.add(pie);
for (Dessert dessert : desserts) {
while (dessert.getAmount() > 0) {
dessert.eat();
System.out.println("Yum! I had some of my of " + dessert.getName() + ".");
}
System.out.println("All out of " + dessert.getName() + " :(");
}
This would give you the following output:
Yum! I had some of my of Chocolate Peanut Butter ice cream.
Yum! I had some of my of Chocolate Peanut Butter ice cream.
Yum! I had some of my of Chocolate Peanut Butter ice cream.
All out of Chocolate Peanut Butter ice cream :(
Yum! I had some of my of Banana Cream pie.
Yum! I had some of my of Banana Cream pie.
All out of Banana Cream pie :(
Now you have a good idea of how to create and use interfaces in Java!