Что такое метод по умолчанию?
После того, как Java 8 выйдет, к интерфейсу могут быть добавлены новые методы, но интерфейс все еще может быть совместим с классом реализации. Это очень важно, потому что библиотека классов, которую вы разрабатываете, может широко использоваться несколькими разработчиками. Перед Java 8, после того, как интерфейс был выпущен в библиотеке классов, если в интерфейс был добавлен новый метод, те приложения, которые реализуют этот интерфейс, будут подвергаться риску сбоя с использованием новой версии интерфейса.
С Java 8 разве нет такой опасности? Ответ нет.
Добавление метода по умолчанию в интерфейс может сделать некоторые классы реализации недоступными.
Во -первых, давайте посмотрим на детали метода по умолчанию.
В Java 8 могут быть реализованы методы в интерфейсах (статические методы в Java 8 также могут быть реализованы в интерфейсах, но это еще одна тема). Метод, реализованный в интерфейсе, называется методом по умолчанию, который идентифицируется по ключевым словам по умолчанию в качестве модификатора. Когда класс реализует интерфейс, он может реализовать методы, которые были реализованы в интерфейсе, но в этом нет необходимости. Этот класс наследует метод по умолчанию. Вот почему, когда интерфейс меняется, класс реализации не нужно изменять.
Как насчет времени, чтобы наследовать больше?
Вещи становятся сложными, когда класс реализует более одного (например, двух) интерфейсов, и эти интерфейсы имеют одинаковый метод по умолчанию. Какой метод по умолчанию наследует класс? Никто из них нет! В этом случае класс должен реализовать метод по умолчанию (только) сам по себе (непосредственно или унаследовать классы более высокого уровня на дереве).
То же самое верно, когда один интерфейс реализует метод по умолчанию, а другой интерфейс объявляет метод по умолчанию как абстрактный. Java 8 пытается избежать неясных вещей и сохранить его строгими. Если метод объявлен в нескольких интерфейсах, то любая реализация по умолчанию не будет унаследована, и вы получите ошибку во время компиляции.
Однако, если вы собрали свой класс, не будет ошибок во времени компиляции. На данный момент Java 8 непоследовательна. У него есть свои причины по разным причинам. Я не хочу подробно объяснять или подробно обсуждать это здесь (потому что: версия была выпущена, и обсуждение было слишком длинной, и эта платформа никогда не обсуждала ее так).
Класс может работать нормально в приведенном выше случае. Однако его нельзя перекомпилировать с помощью модифицированных интерфейсов, но он все еще может работать со старыми интерфейсами. Следующий
Когда оба интерфейса предоставляют реализации по умолчанию к одному и тому же методу, этот метод не может быть вызван, если класс реализации также не реализует метод по умолчанию (либо напрямую реализует его, либо наследует класс более высокого уровня на дереве для реализации).
Однако этот класс совместим. Его можно загрузить с помощью новых интерфейсов или даже выполнить, если он не вызывает метод, который имеет реализацию по умолчанию в обоих интерфейсах.
Пример кода
Чтобы продемонстрировать приведенный выше пример, я создал тестовый каталог для C.Java, который имеет 3 подкаталогов ниже, которые используются для хранения i1.java и i2.java. Справочник по тестированию содержит исходный код C.Java of Class C. Базовый каталог содержит интерфейс для версии, которая может быть составлена и запуска. I1 содержит метод m (), реализованный по умолчанию, и I2 не содержит никаких методов.
Класс реализации содержит основной метод, поэтому мы можем выполнить его в тесте. Он будет проверять, есть ли параметры командной строки, чтобы мы могли легко выполнить тесты, которые вызывают m (), а не вызовать m ().
открытый класс C реализует i1, i2 {public static void main (string [] args) {c c = new c (); if (args.length == 0) {cm (); }}} открытый интерфейс i1 {по умолчанию void m () {System.out.println ("Hello Interface 1"); }} публичный интерфейс i2 {}Используйте следующую командную строку для компиляции и запуска:
javac -cp.: base c.javajava -cp.
Совместимый каталог содержит интерфейс I2 с абстрактным методом m () и немодифицированным интерфейсом I1.
Публичный интерфейс i2 {void m ();}Это не может быть использовано для компиляции класса C:
javac -cp.: совместимый C.Javac.java:1: ошибка: c не является абстрактным и не переопределяет метод абстрактного m () в I2Public Class C Обнаружения i1, i2 { ^ 1 ОшибкаСообщение об ошибке очень точное. Поскольку у нас есть C.class, полученный из предыдущей компиляции, если мы составляем интерфейс в совместимом каталоге, мы все равно получим два интерфейса, которые могут запустить класс реализации:
Javac совместим/i*.javajava -cp.: совместимый интерфейс Chello 1
Третий каталог назвал неправильным, а интерфейс I2, содержащийся также определяет метод m ():
Публичный интерфейс i2 {по умолчанию void m () {System.out.println ("Hello Interface 2"); }}Мы никогда не должны устанавливать его составление. Хотя метод m () определяется дважды, класс реализации все еще может работать до тех пор, пока он не вызывает метод, который был определен несколько раз, но если мы называем метод m (), он сразу не удастся. Вот параметры командной строки, которые мы используем:
javac неправильно/*. javajava -cp.: Неправильное c Исключение в потоке «Main» java.lang.incompatiblasschangeerror: Конфликтные методы по умолчанию: i1.m i2.m at cm (c.java) на C.main (C.Java:5) Java -cp.: Неправильный C X
в заключение
Когда вы портите библиотеку классов, которая добавляет реализацию по умолчанию в интерфейс в среду Java 8, обычно не будет никаких проблем. По крайней мере, это то, что разработчики библиотеки классов Java8 думают при добавлении методов по умолчанию к классам сбора. Приложения, которые используют вашу библиотеку классов, все еще полагаются на библиотеку классов Java7 без метода по умолчанию. При использовании и изменении нескольких различных классовых библиотек существует небольшая вероятность конфликта. Как я могу этого избежать?
Создайте библиотеку классов, как и раньше. Не принимайте это легкомысленно, когда вы можете полагаться на метод по умолчанию. Не используйте его как абсолютно необходимый. Выберите имя метода с умом, чтобы избежать конфликтов с другими интерфейсами. Мы узнаем, как использовать эту функцию для разработки в программировании Java.
Суммировать
Вышеуказанное - все содержание этой статьи. Я надеюсь, что содержание этой статьи имеет определенную справочную ценность для каждого обучения или работы. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения. Спасибо за поддержку Wulin.com.