В Java 8 и более поздних версиях ответ на этот вопрос по-прежнему актуален, но теперь он более детализирован.
Во-первых, эти утверждения из принятого ответа остаются верными:
- интерфейсы предназначены для указания их неявного поведения в контракте (утверждение правил поведения, которым реализующие классы должны подчиняться, чтобы считаться действительными)
- существует различие между контрактом (правилами) и реализацией (программным кодированием правил)
- методы, указанные в интерфейсе, ДОЛЖНЫ быть реализованы ВСЕГДА (в какой-то момент)
Итак, что нового в Java 8? Говоря о «необязательных методах» , теперь уместно любое из следующего:
1. Метод, реализация которого не является обязательной по контракту.
«Третье утверждение» говорит, что методы абстрактного интерфейса должны быть реализованы всегда, и это остается верным в Java 8+. Однако, как и в Java Collections Framework, некоторые абстрактные методы интерфейса можно описать как «необязательные» в контракте.
В этом случае автор, реализующий интерфейс, может отказаться от реализации метода. Однако компилятор будет настаивать на реализации, и поэтому автор использует этот код для любых дополнительных методов, которые не нужны в конкретном классе реализации:
public SomeReturnType optionalInterfaceMethodA(...) {
throw new UnsupportedOperationException();
}
В Java 7 и ранее это был единственный вид «необязательного метода», т. Е. Метод, который, если он не реализован, вызывал исключение UnsupportedOperationException. Это поведение обязательно указывается в контракте интерфейса (например, дополнительные методы интерфейса Java Collections Framework).
2. Метод по умолчанию, повторная реализация которого не является обязательной.
В Java 8 появилась концепция методов по умолчанию . Это методы, реализация которых может быть обеспечена самим определением интерфейса. Как правило, можно предоставить методы по умолчанию только тогда, когда тело метода может быть написано с использованием других методов интерфейса (т. Е. «Примитивов»), и когда this
может означать «этот объект, класс которого реализовал этот интерфейс».
Метод по умолчанию должен выполнять контракт интерфейса (как и любая другая реализация метода интерфейса). Следовательно, определение реализации метода интерфейса в классе реализации остается на усмотрение автора (если поведение соответствует его или ее цели).
В этой новой среде Java Collections Framework может быть переписан как:
public interface List<E> {
:
:
default public boolean add(E element) {
throw new UnsupportedOperationException();
}
:
:
}
Таким образом, «необязательный» метод add()
имеет поведение по умолчанию, выбрасывающее исключение UnsupportedOperationException, если реализующий класс не обеспечивает собственного нового поведения, что именно то, что вы хотели бы иметь, и которое соответствует контракту для List. Если автор пишет класс, который не позволяет добавлять новые элементы в реализацию List, реализация не add()
является обязательной, поскольку поведение по умолчанию - именно то, что необходимо.
В этом случае "третье утверждение" выше по-прежнему остается в силе, потому что метод был реализован в самом интерфейсе.
3. Метод, возвращающий Optional
результат.
Последний новый вид необязательного метода - это просто метод, который возвращает Optional
. Optional
Класс обеспечивает явно более объектно-ориентированный способ борьбы с null
результатами.
В свободном стиле программирования, который обычно наблюдается при кодировании с использованием нового Java Streams API, нулевой результат в любой момент вызывает сбой программы с исключением NullPointerException. Optional
Класс обеспечивает механизм для возврата результатов неопределенной коды клиента таким образом , что дает возможность свободно стиль , не вызывая клиентский код аварию.