12

Раньше interface не имел реализации и нам приходилось реализовывать абстрактные классы. Но сейчас, а конкретно, начиная с 'Java8', interface может иметь реализацию. Зачем так поступили? В чём здесь выигрыш? Какие преимущества дает интерфейс, имеющий реализацию? И главное, в чем тогда смысл использования абстрактных классов, если интерфейс может содержать реализацию методов?

m. vokhm
  • 3,377
elik
  • 5,658

1 Answers1

19

Интерфейс описывает только поведение (методы) и не может иметь состояние (поля), абстрактный класс - может.

В случае с default-методами, поведение может быть не только описано, но и реализовано. Однако по-прежнему без доступа к состоянию.

В Java 8 default-методы были добавлены во многом ради Stream API. Это позволило добавить методы spliterator() и stream() всем коллекциям, которые были написаны до появления Stream API, не затрагивая их реализации:

public interface Iterable<T>
    // ...

    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

public interface Collection<E> extends Iterable<E> {
    // ...

    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, 0);
    }

    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
}

Как видите, default-методы тут ведут себя как миксины, оборачивающие некоторую стороннюю реализацию (Spliterators, StreamSupport) и превращающую ее в честные методы коллекций.


Пример из жизни. Есть интерфейс доступа к данным, который может иметь разные реализации:

public interface Repository {
    Foo getFooWithTimeout(int id, int timeout);
    // ...
}

И хочется иметь его сокращенную версию какого-то метода со значениями параметров по-умолчанию. Тогда достаточно просто обернуть существующий метод default-методом:

public interface Repository {
    Foo getFooWithTimeout(int id, int timeout);

    default Foo getFoo(int id) {
        return getFooWithTimeout(id, 0);
    }
    // ...
}

Мы расширили контракт всех реализаций интерфейса Repository новым методом, при этом никто не пострадал нам не пришлось вторгаться в реализации.

Nofate
  • 34,603
  • Хотел бы добавить, что default-методы - это, еще и шаг в сторону множественного наследования. В Java, класс не может наследоваться от нескольких абстрактных классов, а реализовывать несколько интерфейсов - может. – Sergi Oct 12 '17 at 12:59