Однако они оба имеют реализацию и не являются "экземплярами" в том смысле, что два объекта одного типа, которые реализуют интерфейс, не имеют переменных экземпляра, расположенных внутри интерфейса ... поскольку переменные интерфейсавсе статично и окончательно.
Нет, вы ошиблись.Методы по умолчанию делегируются абстрактным методам.Абстрактные методы реализованы в конкретных классах, которые реализуют интерфейс.У конкретных классов очень много полей экземпляров.
Пример:
interface Counter {
void add(int i);
default void increment() {
this.add(1);
}
}
Реализация
class ConcreteCounter implements Counter {
private int value = 0;
@Override
public void add(int i) {
this.value += i;
}
}
Статический метод, так же как статические методы в классах, не может вызыватьметоды экземпляра и вызываются в самом классе интерфейса, а не в экземпляре этого интерфейса.В приведенном выше примере вы можете, например, иметь
interface Counter {
static Counter createDefault() {
return new ConcreteCounter();
}
void add(int i);
default void increment() {
this.add(1);
}
}
Этот статический метод не может быть реализован как метод по умолчанию: не было бы смысла создавать счетчик, чтобы иметь возможностьсоздать счетчик.
Чтобы привести более конкретный пример, давайте возьмем метод sort()
интерфейса List
.Он сортирует элементы списка и является методом по умолчанию.Он не может быть статическим методом: статический метод не вызывается в экземпляре List, поэтому он не может сортировать его элементы.
Так что, в принципе, разница между методами по умолчанию иСтатические методы в интерфейсах - это то же различие, что и между статическим методом и методом экземпляра в классе.