что такое java interface

27. Java – Интерфейсы

Интерфейс — это ссылочный тип в Java. Он схож с классом. Это совокупность абстрактных методов. Класс реализует интерфейс, таким образом наследуя абстрактные методы интерфейса.

Вместе с абстрактными методами интерфейс в Java может содержать константы, обычные методы, статические методы и вложенные типы. Тела методов существуют только для обычных методов и статических методов.

Далее разберём зачем нужны интерфейсы в Java и для чего используются, разницу абстрактного класса и интерфейса.

Содержание

Написание интерфейса схоже с написанием класса. Но класс описывает атрибуты и поведения объекта. И интерфейс содержит поведения, которые класс реализует.

Если класс, реализующий интерфейс, не является абстрактным, все методы интерфейса должны быть определены в классе.

Чем похожи класс и интерфейс?

Интерфейс схож с классом следующим образом:

Чем отличается класс от интерфейса?

Однако, интерфейс всё же отличается от класса. Отличие интерфейса от класса в Java:

Объявление интерфейсов

Ключевое слово interface используется для объявления интерфейса. Вот пример того, как можно создать интерфейс:

Пример 1

Интерфейсы имеют следующие свойства:

Пример 2

Реализация интерфейса

Когда класс реализует интерфейс, вы можете представить себе, что класс словно подписывает контракт с интерфейсом, соглашаясь совершить конкретные его поведения. Если класс не исполняет все поведения интерфейса, то класс должен объявить себя абстрактным.

Класс использует ключевое слово implements для реализации интерфейса. Ключевое слово implements появляется при объявлении класса в его расширенной части.

Пример

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

При реализации интерфейсов есть некоторые правила:

Расширение интерфейсов

Интерфейс может расширять другой интерфейс так же, как класс другой класс. Ключевое слово extends используется для расширения интерфейса, и дочерний интерфейс наследует методы родительского интерфейса.

Приведённый интерфейс Sports расширен интерфейсами Hockey и Football.

Пример

Интерфейс Hockey имеет четыре метода, но он наследует два из Sports; таким образом, класс, который реализует Hockey, должен реализовать все шесть методов. Подобно этому, класс, который реализует Football, должен определить три метода из Football и два метода из Sports.

Расширение множества интерфейсов

Класс в Java может расширить только один родительский класс. Множественное наследование невозможно. Однако интерфейсы не классы, и интерфейс может расширить более чем один родительский интерфейс.

Ключевое слово extends используется лишь раз, а родительские интерфейсы объявляются через запятую.

Например, если интерфейс Hockey расширил и Sports, и Event, то объявление выглядело бы так:

Интерфейсы тегов

Самое распространённое использование расширения интерфейсов происходит тогда, когда родительский интерфейс не содержит каких-либо методов. Например, интерфейс MouseListener в пакете java.awt.event расширил java.util.EventListener, который определяется так:

Интерфейс без методов в нём называется интерфейсом тегов. Есть две простые дизайнерские цели для интерфейсов тегов:

Создаёт общего родителя – как в случае с интерфейсом EventListener, который расширяется множеством других в Java API, вы можете использовать интерфейс тегов, чтобы создать общего родителя среди группы интерфейсов. Например, когда интерфейс расширяет EventListener, то JVM знает, что этот конкретный интерфейс будет использоваться в сценарии делегирования событий.

Добавляет тип данных в класс – эта ситуация является источником термина «тегирование». Класс, который реализует интерфейс тегов, не должен определять какие-либо методы (т.к. интерфейс не имеет таковых), но класс становится типом интерфейса через полиморфизм.

Источник

Интерфейсы Java – что это такое?

Интерфейс Java немного похож на класс, за исключением того, что интерфейс может содержать только сигнатуры методов и поля. Интерфейс не может содержать реализацию методов, только подпись(имя, параметры и исключения) метода.

Вы можете использовать их как способ достижения полиморфизма.

Пример интерфейса Java

Вот простой пример интерфейса Java:

Как видите, интерфейс объявляется с использованием ключевого слова. Как и в случае с классами, интерфейс может быть объявлен как общедоступный или пакетный(без модификатора доступа).

Приведенный выше пример содержит одну переменную и один метод. Доступ к переменной можно получить непосредственно из интерфейса, например так:

Как видите, доступ к переменной очень похож на доступ к статической переменной в классе.

Однако этот метод должен быть реализован некоторым классом, прежде чем вы сможете получить к нему доступ. Следующий раздел объяснит, как это сделать.

Реализация интерфейса

Вот класс, который реализует интерфейс MyInterface, показанный выше:

Обратите внимание, реализует часть MyInterface вышеупомянутого объявления класса. Это сообщает компилятору Java, что класс MyInterfaceImpl реализует интерфейс MyInterface.

Класс, реализующий интерфейс, должен реализовывать все методы, объявленные в нем. Методы должны иметь точно такую же сигнатуру(имя + параметры), как объявлено. Класс не должен реализовывать(объявлять) переменные интерфейса. Только методы.

Экземпляры интерфейса

Как только класс Java реализует интерфейс Java, вы можете использовать экземпляр этого класса в качестве экземпляра. Вот пример:

Обратите внимание, как объявлена переменная типа интерфейса MyInterface, в то время как созданный объект имеет тип MyInterfaceImpl. Java позволяет это, потому что класс MyInterfaceImpl реализует MyInterface. Затем вы можете ссылаться на экземпляры класса MyInterfaceImpl как на экземпляры MyInterface.

Вы не можете создавать экземпляры интерфейса самостоятельно. Вы должны всегда создавать экземпляр некоторого класса, который реализует интерфейс, и ссылаться на этот экземпляр как на экземпляр интерфейса.

Реализация нескольких интерфейсов

Класс Java может реализовывать несколько интерфейсов. В этом случае класс должен реализовать все методы, объявленные во всех реализованных интерфейсах. Вот пример:

Этот класс реализует два, называемых MyInterface и MyOtherInterface. Вы перечисляете имена для реализации после ключевого слова Implements, разделенных запятой.

Если интерфейсы не находятся в тех же пакетах, что и реализующий класс, вам также необходимо импортировать их. Они импортируются с помощью инструкции импорта. Например:

реализованные классом выше:

Как видите, каждый интерфейс содержит один метод. Эти методы реализуются классом MyInterfaceImpl.

Перекрывающиеся подписи метода

Если класс реализует несколько интерфейсов, существует риск, что некоторые могут содержать методы с одинаковой сигнатурой(имя + параметры). Поскольку класс может реализовывать метод только с заданной сигнатурой только один раз, это может привести к проблемам.

Спецификация не дает никакого решения этой проблемы. Вам решать, что делать в этой ситуации.

Какие типы Java могут реализовывать интерфейсы?

Следующие типы могут реализовывать интерфейсы:

Переменные интерфейса

Интерфейс может содержать как переменные, так и константы. Однако часто не имеет смысла помещать переменные. В некоторых случаях может иметь смысл определять константы.

Читайте также:  какие витамины содержатся в желтке куриных яиц

Особенно, если эти константы должны использоваться классами, например, в вычислениях, или в качестве параметров для некоторых методов. Я советую вам избегать размещения переменных.

Все переменные в интерфейсе являются открытыми, даже если вы опустите ключевое слово public в объявлении переменной.

Методы интерфейса

Интерфейс может содержать одно или несколько объявлений метода. Как упоминалось ранее, он не может указывать какую-либо реализацию для этих методов. Это зависит от классов, чтобы определить реализацию.

Все методы являются открытыми, даже если вы опустите ключевое слово public в объявлении метода.

Методы интерфейса по умолчанию

До Java 8 интерфейсы не могли содержать реализацию методов, а содержали только сигнатуры методов. Однако это приводит к некоторым проблемам, когда API необходимо добавить метод.

Если API просто добавляет метод, все классы, которые реализуют интерфейс, должны реализовать этот новый метод. Это хорошо, если все реализующие классы расположены в API. Но если некоторые реализующие классы находятся в клиентском коде API(код, который использует API), то этот код нарушается.

Посмотрите на этот интерфейс и представьте, что он является частью, например, API с открытым исходным кодом, который многие приложения используют внутри:

Теперь представьте, что проект использует этот API и реализовал ResourceLoader следующим образом:

Если разработчик API хочет добавить еще один метод в ResourceLoader, то класс FileLoader будет нарушен при обновлении этого проекта до новой версии API.

Чтобы облегчить эту проблему, Java 8 добавила концепцию. Метод интерфейса по умолчанию может содержать реализацию этого метода по умолчанию. Классы, которые реализуют интерфейс, но не содержат реализации по умолчанию, автоматически получат реализацию метода по умолчанию.

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

В этом примере добавляется метод загрузки по умолчанию(Path). В примере не учитывается фактическая реализация(внутри тела метода), потому что это не очень интересно. Важно то, как вы объявляете метод по умолчанию.

Класс может переопределить реализацию метода по умолчанию просто путем явной реализации этого метода, как это обычно делается.

Статические методы интерфейса

Статические методы в Java должны иметь реализацию.

Вызов статического метода выглядит и работает так же, как вызов статического метода в классе. Вот пример вызова статического метода print() из вышеуказанного MyInterface:

Статические методы в интерфейсах могут быть полезны, когда у вас есть несколько служебных методов, которые вы хотели бы сделать доступными. Например, Vehicle может иметь статический метод printVehicle(Vehicle v).

Интерфейсы и наследование

Интерфейс Java может наследоваться от другого, как классы могут наследовать от других классов. Вы указываете наследование, используя ключевое слово extends.

MySubInterface расширяет MySuperInterface. Это означает, что MySubInterface наследует все поля и методы от MySuperInterface. Это означает, что если класс реализует MySubInterface, этот класс должен реализовать все методы, определенные как в MySubInterface, так и в MySuperInterface.

Можно определить методы в подинтерфейсе с той же сигнатурой(имя + параметры), что и методы, определенные в суперинтерфейсе, если вы считаете, что это будет лучше в вашем проекте.

В отличие от классов, интерфейсы могут наследоваться от нескольких суперинтерфейсов. Вы указываете это, перечисляя имена всех интерфейсов для наследования, разделенных запятой. Класс, реализующий интерфейс, который наследуется от нескольких, должен реализовывать все методы интерфейса и его суперинтерфейсов.

Вот пример интерфейса Java, который наследуется от нескольких интерфейсов:

Как и при реализации нескольких интерфейсов, не существует правил для того, как вы обрабатываете ситуацию, когда несколько суперинтерфейсов имеют методы с одинаковой сигнатурой(имя + параметры).

Наследование и методы по умолчанию

Методы интерфейса по умолчанию немного усложняют правила наследования интерфейса. Хотя обычно класс может реализовать несколько интерфейсов, даже если интерфейсы содержат методы с одинаковой сигнатурой, это невозможно, если один или несколько из этих методов являются методами по умолчанию. Другими словами, если два интерфейса содержат одну и ту же сигнатуру метода(имя + параметры) и один из интерфейсов объявляет этот метод как метод по умолчанию, класс не может автоматически реализовать оба интерфейса.

Ситуация такая же, если интерфейс расширяет(наследует) несколько интерфейсов, и один или несколько из этих интерфейсов содержат методы с одинаковой сигнатурой, а один из суперинтерфейсов объявляет перекрывающийся метод как метод по умолчанию.

В обеих вышеупомянутых ситуациях компилятор Java требует, чтобы класс, реализующий интерфейс(ы), явно реализовал метод, который вызывает проблему. Таким образом, нет сомнений в том, какую реализацию будет иметь класс. Реализация в классе имеет приоритет над любыми реализациями по умолчанию.

Интерфейсы и полиморфизм

Java-интерфейсы – это способ достижения полиморфизма. Полиморфизм – это концепция, которая требует некоторой практики и мысли, чтобы овладеть ею. По сути, полиморфизм означает, что экземпляр класса(объекта) можно использовать так, как если бы он был разных типов. Здесь тип означает либо класс, либо интерфейс.

Посмотрите на эту простую диаграмму классов:

Приведенные выше классы являются частями модели, представляющей различные типы транспортных средств и водителей, с полями и методами. Это ответственность этих классов – моделировать эти сущности из реальной жизни.

Теперь представьте, что вам нужно иметь возможность хранить эти объекты в базе данных, а также сериализовать их в XML, JSON или другие форматы. Вы хотите, чтобы это было реализовано с использованием одного метода для каждой операции, доступного для каждого объекта Car, Truck или Vehicle. Метод store(), метод serializeToXML() и метод serializeToJSON().

Пожалуйста, забудьте на некоторое время, что реализация этой функциональности как методов непосредственно на объектах может привести к грязной иерархии классов. Просто представьте, что именно так вы хотите выполнить операции.

Где в приведенной выше схеме вы бы поместили эти три метода, чтобы они были доступны для всех классов?

Одним из способов решения этой проблемы было бы создание общего суперкласса для класса Vehicle и Driver, который имеет методы хранения и сериализации. Однако это приведет к концептуальному беспорядку. Иерархия классов больше не будет моделировать транспортные средства и водителей, но также будет привязана к механизмам хранения и сериализации, используемым в вашем приложении.

Лучшим решением было бы создать некоторые интерфейсы с включенными методами хранения и сериализации и позволить классам реализовать эти интерфейсы. Вот примеры таких интерфейсов:

Читайте также:  что делать при попадании инородного тела в дыхательные пути

Когда каждый класс реализует эти два интерфейса и их методы, вы можете получить доступ к методам этих интерфейсов, приведя объекты к экземплярам типов интерфейса. Вам не нужно точно знать, к какому классу относится данный объект, если вы знаете, какой интерфейс он реализует.

Как вы уже, наверное, можете себе представить, интерфейсы предоставляют более понятный способ реализации сквозных функций в классах, чем наследование.

Универсальные интерфейсы

Этот интерфейс представляет интерфейс, который содержит единственный метод, который называется производством(), который может произвести единственный объект. Так как возвращаемое значение yield() – Object, он может возвращать любой объект Java.

Как вы можете видеть, поскольку универсальный тип для экземпляра CarProducer установлен на Car, больше нет необходимости приводить объект, возвращенный из метода yield(), поскольку в объявлении исходного метода в интерфейсе MyProducer указано, что этот метод возвращает тот же тип, который указан в универсальном типе при использовании.

Как вы можете видеть, по-прежнему нет необходимости приводить объект, возвращаемый функциейручки(), поскольку реализация CarProducer объявляет, что это экземпляр Car.

Обобщения Java более подробно описаны в моем руководстве по обобщению Java.

Функциональные интерфейсы

Источник

Интерфейсы в Java и немного о полиморфизме

Интерфейс – это контракт, в рамках которого части программы, зачастую написанные разными людьми, взаимодействуют между собой и со внешними приложениями. Интерфейсы работают со слоями сервисов, безопасности, DAO и т.д. Это позволяет создавать модульные конструкции, в которых для изменения одного элемента не нужно трогать остальные.

Новички часто спрашивают, чем интерфейс отличается от абстрактного класса. Интерфейсы в Java компенсируют отсутствие множественного наследования классов. У класса-потомка может быть только один абстрактный класс-родитель, а вот интерфейсов класс может применять (имплементировать) сколько угодно.

Интерфейс на Java объявляют примерно так же, как и класс:

В имплементирующем интерфейс классе должны быть реализованы все предусмотренные интерфейсом методы, за исключением методов по умолчанию.

Методы по умолчанию впервые появились в Java 8. Их обозначают модификатором default. В нашем примере это метод say_goodbye, реализация которого прописана прямо в интерфейсе. Дефолтные методы изначально готовы к использованию, но при необходимости их можно переопределять в применяющих интерфейс классах.

Функциональный интерфейс Java

Если у интерфейса только один абстрактный метод, перед нами функциональный интерфейс. Его принято помечать аннотацией @FunctionalInterface, которая указывает компилятору, что при обнаружении второго абстрактного метода в этом интерфейсе нужно сообщить об ошибке. Стандартных (default) методов у интерфейса может быть множество – в том числе принадлежащих классу java.lang.Object.

Как выглядит функциональный интерфейс на Java:

Функциональные интерфейсы появились в Java 8. Они обеспечили поддержку лямбда-выражений, использование которых делает код лаконичным и понятным:

В той же версии появились пакеты встроенных интерфейсов: java.util.function и java.util.stream.

Реализация интерфейсов классами Java

Допустим, есть интерфейс Edible, которым пользуются классы Fruit, Vegetable, Fish. Экземпляры этих классов можно создавать так:

Обратите внимание на разницу в конструкторах: для фруктов задаём название и сорт, для рыбы – название, район вылова и вес порции в граммах. Но ссылки на оба объекта храним в переменных одного типа – «Съестное».

Интерфейсы и полиморфизм

Пример выше иллюстрирует один из трех основополагающих принципов ООП — полиморфизм. Мы раскрыли одно и то же явление — съедобность — через несколько классов, свойства и методы которых частично отличаются. Представление разных форм одного явления — это и есть полиморфизм. Если нужно, такую систему всегда можно расширить и скорректировать. В нашем случае — добавить новые виды съестного и методы их приготовления.

В Java полиморфизм можно реализовать через:

Интерфейс выручает в ситуации, когда при создании переменной мы не знаем, объект какого класса ей будет присвоен.

Интерфейс – это контракт, в рамках которого части программы, зачастую написанные разными людьми, взаимодействуют между собой и со внешними приложениями. Интерфейсы работают со слоями сервисов, безопасности, DAO и т.д. Это позволяет создавать модульные конструкции, в которых для изменения одного элемента не нужно трогать остальные.

Новички часто спрашивают, чем интерфейс отличается от абстрактного класса. Интерфейсы в Java компенсируют отсутствие множественного наследования классов. У класса-потомка может быть только один абстрактный класс-родитель, а вот интерфейсов класс может применять (имплементировать) сколько угодно.

Интерфейс на Java объявляют примерно так же, как и класс:

В имплементирующем интерфейс классе должны быть реализованы все предусмотренные интерфейсом методы, за исключением методов по умолчанию.

Методы по умолчанию впервые появились в Java 8. Их обозначают модификатором default. В нашем примере это метод say_goodbye, реализация которого прописана прямо в интерфейсе. Дефолтные методы изначально готовы к использованию, но при необходимости их можно переопределять в применяющих интерфейс классах.

Функциональный интерфейс Java

Если у интерфейса только один абстрактный метод, перед нами функциональный интерфейс. Его принято помечать аннотацией @FunctionalInterface, которая указывает компилятору, что при обнаружении второго абстрактного метода в этом интерфейсе нужно сообщить об ошибке. Стандартных (default) методов у интерфейса может быть множество – в том числе принадлежащих классу java.lang.Object.

Как выглядит функциональный интерфейс на Java:

Функциональные интерфейсы появились в Java 8. Они обеспечили поддержку лямбда-выражений, использование которых делает код лаконичным и понятным:

В той же версии появились пакеты встроенных интерфейсов: java.util.function и java.util.stream.

Реализация интерфейсов классами Java

Допустим, есть интерфейс Edible, которым пользуются классы Fruit, Vegetable, Fish. Экземпляры этих классов можно создавать так:

Обратите внимание на разницу в конструкторах: для фруктов задаём название и сорт, для рыбы – название, район вылова и вес порции в граммах. Но ссылки на оба объекта храним в переменных одного типа – «Съестное».

Интерфейсы и полиморфизм

Пример выше иллюстрирует один из трех основополагающих принципов ООП — полиморфизм. Мы раскрыли одно и то же явление — съедобность — через несколько классов, свойства и методы которых частично отличаются. Представление разных форм одного явления — это и есть полиморфизм. Если нужно, такую систему всегда можно расширить и скорректировать. В нашем случае — добавить новые виды съестного и методы их приготовления.

В Java полиморфизм можно реализовать через:

Интерфейс выручает в ситуации, когда при создании переменной мы не знаем, объект какого класса ей будет присвоен.

Читайте также:  что значит пустить хмурого по вене

Источник

История эволюции интерфейсов в Java

Интерфейс в Java сильно эволюционировал за прошедшие годы. Давайте рассмотрим, какие изменения произошли в процессе его развития.

Оригинальные интерфейсы

Интерфейсы в Java 1.0 были достаточно простыми по сравнению с тем, какие они сейчас. Они могли содержать лишь два типа элементов: константы и публичные абстрактные методы.

Поля-константы

Интерфейсы могут содержать поля, так же как и обычные классы, но с несколькими отличиями:

Даже несмотря на то, что явно это не задано, поле MY_CONSTANT считается публичной статической финальной константой. Вы можете добавить эти модификаторы, но делать это не обязательно.

Абстрактные методы

Наиболее важными элементами интерфейса являются его методы. Методы интерфейса также отличаются от методов обычного класса:

Вложенность

Java 1.1 представила концепцию классов, которые можно размещать внутри других классов. Такие классы бывают двух видов: статические и нестатические. Интерфейсы так же могут содержать внутри себя другие интерфейсы и классы.

Даже если это не задано явно, такие интерфейсы и классы считаются публичными и статическими.

Перечисления и аннотации

В Java 5 были введены ещё два типа: Перечисления и Аннотации. Они также могут быть помещены внутрь интерфейсов.

Обобщенные типы

Java 5 ввела концепцию «дженериков» — обобщенных типов. Вкратце: «дженерики» позволяют вам использовать обобщенный тип вместо указания конкретного типа. Таким образом, вы можете писать код, который работает с различным количеством типов, не жертвуя при этом безопасностью и не предоставляя отдельную реализацию для каждого типа.

В интерфейсах, начиная с Java 5, вы можете определить обобщенный тип, а затем использовать его в качестве типа возвращаемого значения метода или в качестве типа аргумента метода.

Интерфейс Box работает независимо от того, используете ли вы его для хранения объектов типа String, Integer, List, Shoe или каких-либо других.

Статические методы

Начиная с Java 8, вы можете включать в интерфейсы статические методы. Данный подход изменил привычный для нас способ работы интерфейса. Они теперь работают совсем не так, как работали до Java 8. Первоначально все методы в интерфейсах были абстрактными. Это означало, что интерфейс предоставлял лишь сигнатуру, но не реализацию. Реализация оставалась за классами, реализующими ваш интерфейс.

При использовании статических методов в интерфейсах вам нужно также предоставить реализацию тела метода. Чтобы задействовать в интерфейсе такой метод, просто используйте ключевое слово static. Статические методы считаются публичными по умолчанию.

Наследование статических методов

В отличие от обычных статических методов, статические методы в интерфейсах не наследуются. Это означает, что если вы хотите вызвать такой метод, вы должны вызвать его напрямую из интерфейса, а не из реализующего его класса.

Это поведение очень полезно для избежания проблем при множественном наследовании. Представьте, что у вас есть класс, реализующий два интерфейса. У каждого из интерфейсов есть статический метод с одинаковым именем и сигнатурой. Какой из них должен быть использован в первую очередь?

Почему это полезно

Представьте, что у вас есть интерфейс и целый набор вспомогательных методов, которые работают с классами, реализующими этот интерфейс.

Традиционно существовал подход в использовании класса-компаньона. В дополнение к интерфейсу создавался утилитный класс с очень похожим именем, содержащий статические методы, принадлежащие интерфейсу.

Вы можете найти примеры использования данного подхода прямо в JDK: интерфейс java.util.Collection и сопутствующий ему утилитный класс java.util.Collections.

Со статическими методами в интерфейсах этот подход больше не актуален, не нужен и не рекомендован. Теперь вы можете иметь все в одном месте.

Методы по умолчанию

Методы по умолчанию похожи на статические методы тем, что для них вы также должны предоставлять тело. Чтобы объявить метод по умолчанию, просто используйте ключевое слово default.

В отличие от статических методов, методы по умолчанию наследуются классами, реализующими интерфейс. Что важно, такие классы могут при необходимости переопределять их поведение.

Хотя есть одно исключение. В интерфейсе не может быть методов по умолчанию с такой же сигнатурой, как у методов toString, equals и hashCode класса Object. Взгляните на ответ Брайана Гетца, чтобы понять обоснованность такого решения: Allow default methods to override Object’s methods.

Почему это полезно

Идея с реализацией методов прямо в интерфейсе выглядит не совсем правильной. Так почему в первую очередь была введена эта функциональность?

У интерфейсов есть одна проблема. Как только вы предоставите свой API другим людям, он навсегда «окаменеет» (его нельзя будет изменить безболезненно).

По традиции, Java очень серьезно относится к обратной совместимости. Методы по умолчанию предоставляют способ расширить существующие интерфейсы новыми методами. Наиболее важно то, что методы по умолчанию уже предоставляют определенную реализацию. Это означает, что классам, реализующим ваш интерфейс, не нужно реализовывать какие-либо новые методы. Но, если в этом будет необходимость, методы по умолчанию можно будет переопределить в любое время, если их реализация перестанет подходить. Таким образом, вкратце, вы можете предоставить новую функциональность существующим классам, реализующим ваш интерфейс, сохраняя при этом совместимость.

Конфликты

Давайте представим, что у нас есть класс, реализующий два интерфейса. У этих интерфейсов есть метод по умолчанию с одинаковыми именем и сигнатурой.

Теперь один и тот же метод по умолчанию с одной и той же сигнатурой унаследован от двух разных интерфейсов. У каждого интерфейса своя реализация этого метода.

Итак, как наш класс узнает, какую из двух различных реализаций использовать?

Он и не узнает. Приведенный выше код приведет к ошибке компиляции. Если вам требуется заставить его работать, то для этого необходимо переопределить конфликтный метод в вашем классе.

Приватные методы

С появлением Java 8 и введением методов по умолчанию и статических методов, у интерфейсов появилась возможность содержать не только сигнатуры методов, но и их реализации. При написании таких реализаций рекомендуется разделять сложные методы на более простые. Такой код легче переиспользовать, поддерживать и понимать.

Для такой цели вы бы использовали приватные методы, поскольку они могут содержать все детали реализации, которые не должны быть видимы и использованы извне.

К сожалению в Java 8 интерфейс не может содержать приватные методы. Это означает, что вы можете использовать:

Хронологический порядок

Ниже представлен хронологический перечень изменений по версиям Java:

Источник

Строительный портал