Что такое реализация метода "по умолчанию", определенная в интерфейсе?
В интерфейсе коллекции я нашел метод с именем removeIf()
, который содержит ее реализации.
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
Я хочу знать, есть ли способ определить тело метода в интерфейсе?
Что такое default
ключевое слово и как оно работает?
3 ответа:
Java 8 вводит "метод по умолчанию" или (методы защитника) новую функцию, которая позволяет разработчику добавлять новые методы к интерфейсам, не нарушая существующую реализацию этого интерфейса. Это обеспечивает гибкость, позволяющую интерфейсу определять реализацию, которая будет использоваться по умолчанию в ситуации, когда конкретный класс не может обеспечить реализацию для этого метода.
public interface A { default void foo(){ System.out.println("Calling A.foo()"); } } public class ClassAB implements A { }
есть один общий вопрос, который люди задают о методах по умолчанию, когда они слышат о новой функции в первый раз:
Что делать, если класс реализует два интерфейса и оба эти интерфейса определяют метод по умолчанию с той же сигнатурой?
пример для иллюстрации этой ситуации:
public interface A { default void foo(){ System.out.println("Calling A.foo()"); } } public interface B { default void foo(){ System.out.println("Calling B.foo()"); } } public class ClassAB implements A, B { }
этот код не удается скомпилировать со следующим результатом:
java: class Clazz inherits unrelated defaults for foo() from types A and B
чтобы исправить это, в Clazz, мы должны решить его вручную, переопределив конфликтующий метод:
public class Clazz implements A, B { public void foo(){} }
но что, если мы хотелось бы вызвать реализацию по умолчанию метода foo () из интерфейса A вместо реализации нашей собственной.
можно ссылаться на#foo () следующим образом:
public class Clazz implements A, B { public void foo(){ A.super.foo(); } }
эти методы называются методами по умолчанию. метод по умолчанию или способ защитник один из новые возможности в Java 8.
они будут использоваться, чтобы позволить интерфейсному методу обеспечить реализацию, используемую по умолчанию в случае, если конкретный класс не предоставляет реализацию для этого метода.
Итак, если у вас есть интерфейс, с помощью метод по умолчанию:
public interface Hello { default void sayHello() { System.out.println("Hello"); } }
следующий класс совершенно справедливо:
public class HelloImpl implements Hello { }
если вы создадите экземпляр
HelloImpl
:Hello hello = new HelloImpl(); hello.sayHello(); // This will invoke the default method in interface
Полезные Ссылки:
Я сделал немного исследования, и я нашел следующее. Надеюсь, это поможет.
существующие проблемы
обычные интерфейсные методы, объявленные как абстрактные и должны быть определены в классе, который реализует интерфейс. Это "обременяет" разработчика класса ответственностью за реализацию каждого объявленного метода. Что еще более важно, это также означает, что расширение интерфейса невозможно после "публикации". В противном случае все исполнители имели бы адаптировать их реализацию, нарушая обратную исходную и бинарную совместимость.
решение, принятое в Java 8
чтобы справиться с этими проблемами, одной из новых функций JDK 8 является возможность расширения существующих интерфейсов с помощью методов по умолчанию. методы по умолчанию не только объявлены, но и определены в интерфейсе.
важные моменты, чтобы отметить
- реализаторы смогут выберите не реализовывать методы по умолчанию в реализованный класс.
- разработчики все еще могут переопределить значение по умолчанию методы, такие как обычные методы класса non-final, могут быть переопределены в подклассы.
- абстрактные классы могут даже (re)объявлять методы по умолчанию как абстрактный, заставляя подклассы переопределять метод (иногда называется "re-abstraction").