An interface defines a set of method signatures, as contract. It can greatly increase code modularity. Often, interfaces are property-driven.
interface CanWalk {
void walkLeft();
void walkRight();
}
There is no method body. So if a class implements CanWalk, he makes the promise to offer those methods:
class Player implements CanWalk {
int x;
@Override
void walkLeft() {
x--;
}
@Override
void walkRight() {
x++;
}
}
Someone could now demand a CanWalk instance and use the methods:
class Mover {
static void moveAround(CanWalk canWalk) {
for (int i = 0; i < 10; i++) {
canWalk.walkRight();
}
canWalk.walkLeft();
canWalk.walkRight();
}
}
Note that the moveAround accepts everything that can walk.
Mover.moveAround(player);
We could also give it a Dog, as long as it implements CanWalk.
You have two options to create instances of interfaces:
- Create a class that
implements the interface, like Player
- Use an anonymous class:
CanWalk canWalk = new CanWalk() {
@Override
void walkLeft() {
System.out.println("Walking left");
}
@Override
void walkRight() {
System.out.println("Walking right");
}
};
An interface that only offers one method is called a functional interface:
@FunctionalInterface
interface IntOperation {
int operate(int a, int b);
}
You have two additional options to create instances of it:
3. Lambda expression
IntOperation operation = (a, b) -> a * b;
System.out.println(operation.operate(5, 3));
- Method reference
static int multiply(int a, int b) {
return a * b;
}
IntOperation operation = MathUtil::multiply;
System.out.println(operation.operate(5, 3));