Есть одно применение для них, как по мне.
Простыми словами: они нужны, чтобы хранить несколько обьектов разных типов в массивах.
Например:
public class Main {
private static Printer[] example;
public static void main(String[] args) {
example = new Printer[] {
new ThisPrint(),
new IsPrint(),
new APrint(),
new ExamplePrint()
};
example[0].print();
example[1].print();
example[2].print();
example[3].print();
}
}
interface Printer {
public void print();
}
class ThisPrint implements Printer {
@Override
public void print() {
System.out.print("This ");
}
}
class IsPrint implements Printer {
@Override
public void print() {
System.out.print("is ");
}
}
class APrint implements Printer {
@Override
public void print() {
System.out.print("a ");
}
}
class ExamplePrint implements Printer {
@Override
public void print() {
System.out.println("example!");
}
}
Других применений я не вижу.