До выпуска Java 8 интерфейсы могли содержать только константы и объявления методов. С появлением Java 8 возможности использования интерфейсов заметно расширились - стало допустимым определять static методы, а также реализовывать методы в теле интерфейсов (используя модификатор default):
public interface TestLogger {
default void log(String msg) {
if (msg != null) {
System.out.println("Log message: " + msg);
} else {
System.out.println("Check passed message");
}
}
default void warn(String msg) {
if (msg != null) {
System.out.println("Warning: " + msg);
} else {
System.out.println("Check passed message");
}
}
}
В Java 9 добавились новые возможности описания интерфейсов. Теперь интерфейсы помимо default методов могут содержать private методы. Это сделано, чтобы можно было вынести общие части реализации из default-методов (если таковые имеются) в отдельные методы и убрать повторяющиеся части кода:
public interface TestLogger {
private void printMsg(String txt, String msg) {
if (msg != null) {
System.out.println(txt + ": " + msg);
} else {
System.out.println("Check passed message");
}
}
default void log(String msg) {
printMsg("Log message", msg);
}
default void warn(String msg) {
printMsg("Warning", msg);
}
}
}
Кроме того, стало возможным добавлять private static методы.
Для запуска небольших фрагментов кода я рекомедую использовать еще одно нововведение Java 9 - jshell (при необходимости прописав его в ClassPath):
jshell> /open <path>/TestLogger.java
jshell> TestLogger tl = new TestLogger(){};
tl ==> 1@59f99ea
jshell> tl.log("Hello");
Log message: Hello