Каков метод по умолчанию?
С выпуском Java 8 к интерфейсу можно добавлять новые методы, но интерфейс по-прежнему может оставаться совместимым с реализующими его классами. Это очень важно, потому что разрабатываемая вами библиотека классов может широко использоваться многими разработчиками. До Java 8 после того, как интерфейс был выпущен в библиотеке классов, если к интерфейсу добавлялся новый метод, те приложения, которые реализовывали интерфейс, подвергались риску сбоя при использовании новой версии интерфейса.
С Java 8 такой опасности нет? ответ отрицательный.
добавить в интерфейсdefaultметоды могут сделать некоторые реализующие классы недоступными.
Во-первых, давайте посмотрим наdefaultподробности метода.
В Java 8 методы в интерфейсе могут быть реализованы (в Java 8staticметоды также могут быть реализованы в интерфейсах, но это уже другая тема). Методы, реализованные в интерфейсе, называютсяdefaultметод с ключевым словомdefaultидентифицируется как модификатор. Когда класс реализует интерфейс, он может реализовывать методы, которые уже реализованы в интерфейсе, но это не обязательно. Этот класс будет наследоватьdefaultметод. Вот почему при изменении интерфейса класс реализации не должен меняться.
Как насчет множественного наследования?
Когда класс реализует более одного (например, два) интерфейса с одинаковымиdefaultметод, все усложняется. какой класс наследуетdefaultметод? Ни один! В этом случае класс реализует себя (либо напрямую, либо из класса выше по дереву наследования)defaultспособ (единственно возможный).
Когда реализован интерфейсdefaultметод, другой интерфейс помещаетdefaultОбъявление метода становитсяabstractвремя, то же самое верно. Java 8 пытается избежать двусмысленности и соблюдать строгость. Если метод объявлен в нескольких интерфейсах, то любойdefaultРеализация не будет унаследована, и вы получите ошибку времени компиляции.
Однако, если вы скомпилировали свой класс, ошибок времени компиляции не будет. Java 8 на данный момент непоследовательна. На это есть свои причины, по разным причинам, и я не хочу вдаваться в подробности или подробно обсуждать это здесь (потому что: версия вышла, обсуждение слишком длинное, на этой платформе никогда не было такого обсуждения) .
- Предположим, у вас есть два интерфейса, один реализующий класс.
- Один из интерфейсов реализуетdefaultметодm().
- Скомпилируйте интерфейс и класс реализации вместе.
- Изменить, что не содержитm()интерфейс метода, объявленныйm()методabstract.
- Перекомпилируйте измененный интерфейс отдельно.
- Запустите класс реализации.
В приведенном выше случае класс работает нормально. Однако перекомпилировать с измененным интерфейсом нельзя, но компиляция со старым интерфейсом все равно будет работать. следующий
- изменить, который содержитabstractметодm()интерфейс, создатьdefaultвыполнить.
- Скомпилируйте модифицированный интерфейс
- Класс запуска: не удалось.
Когда два интерфейса предоставляют реализацию по умолчанию для одного и того же метода, этот метод нельзя вызвать, если класс реализации также не реализует метод по умолчанию (либо напрямую, либо с помощью класса выше в дереве наследования).
Однако этот класс совместим. Его можно загрузить с помощью нового интерфейса или даже выполнить, если он не вызывается в обоих интерфейсах.defaultспособ реализовать.
пример кода
Чтобы продемонстрировать приведенный выше пример, я даюC.javaСоздан тестовый каталог с 3 подкаталогами для храненияI1.javaиI2.java. Каталог test содержит исходный код класса CC.java. Базовый каталог содержит версию интерфейса, которую можно скомпилировать и запустить. I1 содержитdefaultосуществленныйm()метод,I2Не содержит никаких методов.
Класс реализации содержитmainметод, поэтому мы можем выполнить его в наших тестах. Он проверяет наличие аргументов командной строки, чтобы мы могли легко выполнить вызовm()и не звонитm()тест.
public class C implements I1, I2 {
public static void main(String[] args) {
C c = new C();
if(args.length == 0 ){
c.m();
}
}
}
public interface I1 {
default void m(){
System.out.println("hello interface 1");
}
}
public interface I2 {
}
Используйте следующую командную строку для компиляции и запуска:
javac -cp .:base C.java
java -cp .:base C
hello interface 1
compatibleкаталог содержитabstractметодm()изI2интерфейс и без измененийI1интерфейс.
public interface I2 {
void m();
}
Это нельзя использовать для компиляции класса C:
javac -cp .:compatible C.java
C.java:1: error: C is not abstract and does not override abstract method m() in I2
public class C implements I1, I2 {
^
1 error
Сообщение об ошибке очень точное. Потому что у нас есть предыдущая компиляцияC.class, если мы скомпилируемcompatibleИнтерфейс под каталогом, мы по-прежнему получаем два интерфейса, которые могут запускать класс реализации:
javac compatible/I*.java
java -cp .:compatible C
hello interface 1
Третий называетсяwrongкаталог, содержащийI2Интерфейс также определяетm()метод:
public interface I2 {
default void m(){
System.out.println("hello interface 2");
}
}
Мы должны потрудиться, чтобы скомпилировать его. Несмотря на то, что метод m() определен дважды, реализующий класс все еще может работать, если он не вызывает метод, который определен более одного раза, но как только мы вызываем метод m(), он немедленно завершается ошибкой. Вот аргументы командной строки, которые мы используем:
javac wrong/*.java
java -cp .:wrong C
Exception in thread "main" java.lang.IncompatibleClassChangeError: Conflicting
default methods: I1.m I2.m
at C.m(C.java)
at C.main(C.java:5)
java -cp .:wrong C x
в заключении
Когда вы добавляете в интерфейсdefaultКогда реализованная библиотека классов переносится в среду Java 8, обычно проблем не возникает. По крайней мере, так думали разработчики библиотек Java 8, когда добавляли методы по умолчанию в классы коллекций. Приложения, использующие вашу библиотеку, по-прежнему зависят отdefaultметоды в библиотеке классов Java7. При использовании и изменении нескольких разных библиотек существует небольшая вероятность конфликтов. Как этого избежать?
Создайте свою библиотеку классов, как и раньше. может зависеть отdefaultНе относитесь к этому легкомысленно, когда дело доходит до методов. Не используйте его в качестве крайней меры. Выбирайте имена методов с умом, чтобы избежать конфликтов с другими интерфейсами. Мы узнаем, как использовать эту функцию для разработки в программировании на Java.
Добро пожаловать в колонку"Идти в ногу с Java 8", делитесь превосходными руководствами и учебными пособиями по китайскому языку Java8 и приветствуйте высококачественные статьи.
Оригинальная ссылка:javacodegeeks
перевести:ImportNew.com - miracle1919
Ссылка на перевод:www.importnew.com/10764.html