Java Interfaces
An interface describes what a class can do, without saying how. It is a list of method headings that a class promises to provide. A class can extend only one superclass, but it can implement as many interfaces as it likes. Interfaces are everywhere in Java: Comparable, Runnable, List and Map are all interfaces.
Defining and implementing an interface
The methods of an interface are automatically public and abstract. A class that implements the interface must provide all of them:
interface Playable {
void play();
}
class Guitar implements Playable {
@Override
public void play() {
System.out.println("Strum strum");
}
}
class Drum implements Playable {
@Override
public void play() {
System.out.println("Boom boom");
}
}
public class Main {
public static void main(String[] args) {
Playable[] band = {new Guitar(), new Drum(), new Guitar()};
for (Playable p : band) {
p.play();
}
}
}Strum strum Boom boom Strum strum
Just as with Polymorphism, the interface can be used as a type: the array holds any Playable object, and each one plays in its own way. Because interface methods are public, the implementations must be public too.
Several interfaces
A class can implement several interfaces, and it can also extend a class at the same time:
interface Swimmer {
void swim();
}
interface Flyer {
void fly();
}
class Bird {
protected final String name;
Bird(String name) {
this.name = name;
}
}
class Duck extends Bird implements Swimmer, Flyer {
Duck() {
super("Duck");
}
public void swim() {
System.out.println(name + " paddles on the pond.");
}
public void fly() {
System.out.println(name + " flies south.");
}
}
public class Main {
public static void main(String[] args) {
Duck d = new Duck();
d.swim();
d.fly();
Swimmer s = d;
s.swim();
}
}Duck paddles on the pond. Duck flies south. Duck paddles on the pond.
Default and static methods
An interface can also contain default methods, which have a body. Every class gets them for free and may override them. Static methods belong to the interface itself:
interface Greeter {
String name();
default String greet() {
return "Hello, " + name() + "!";
}
static Greeter of(String n) {
return () -> n;
}
}
class Robot implements Greeter {
public String name() {
return "R2";
}
@Override
public String greet() {
return "BEEP. " + Greeter.super.greet();
}
}
public class Main {
public static void main(String[] args) {
System.out.println(new Robot().greet());
System.out.println(Greeter.of("Asha").greet());
}
}BEEP. Hello, R2! Hello, Asha!
The () -> n in of is a lambda expression, a short way to implement an interface that has only one abstract method. The Lambda topic explains it fully.
Comparable: an interface from the library
When a class implements Comparable, Java knows how to sort its objects. compareTo returns a negative number, zero or a positive number, like the string compareTo from Strings:
import java.util.Arrays;
class Player implements Comparable<Player> {
final String name;
final int score;
Player(String name, int score) {
this.name = name;
this.score = score;
}
public int compareTo(Player other) {
return Integer.compare(other.score, score);
}
public String toString() {
return name + "=" + score;
}
}
public class Main {
public static void main(String[] args) {
Player[] players = {new Player("Ana", 40), new Player("Raj", 75), new Player("Lee", 60)};
Arrays.sort(players);
System.out.println(Arrays.toString(players));
}
}[Raj=75, Lee=60, Ana=40]
Comparable<Player> uses generics, which you will meet later; it means "comparable with other players". Comparing other.score with score (in that order) sorts from the highest score down.
Practice exercises
- Write an interface
Shapewitharea()and two classes that implement it. - Add a default method
describe()to the interface that prints the area. - Make a
Bookclass implementComparable<Book>so that books sort by title.