Интерфейс в Java похож на класс, но тело интерфейса может включать только абстрактные методы и
final
поля (константы).
Недавно я увидел вопрос, который выглядит так
interface AnInterface {
public default void myMethod() {
System.out.println("D");
}
}
Согласно определению интерфейса, разрешены только абстрактные методы . Почему это позволяет мне скомпилировать приведенный выше код? Какое default
ключевое слово?
С другой стороны, когда я пытался написать код ниже, он говорит modifier default not allowed here
default class MyClass{
}
вместо того
class MyClass {
}
Может ли кто-нибудь сказать мне цель default
ключевого слова? Разрешено ли это только внутри интерфейса? Чем он отличается от default
(без модификатора доступа)?
Ответы:
Это новая функция в Java 8, которая позволяет
interface
предоставлять реализацию. Описан в Java 8 JLS-13.5.6. Объявления метода интерфейса, который читает (частично)Что нового в JDK 8 говорит (частично)
источник
private
методы.private
методы на самом деле не являются частью интерфейса, но могут служить вспомогательными методами дляdefault
реализаций или внутри постоянных инициализаторов. Обратите внимание, что они уже существуют в Java 8, так как при использовании лямбда-выражений в интерфейсахprivate
создаются синтетические методы. Таким образом, Java 9 позволяет вам использовать эту функцию также для несинтетических, не лямбда-выражений…Методы по умолчанию были добавлены в Java 8 в первую очередь для поддержки лямбда-выражений. Дизайнеры (на мой взгляд, хитроумно) решили создать синтаксис лямбда-выражений для создания анонимных реализаций интерфейса. Но учитывая, что лямбды могут реализовывать только один метод, они будут ограничены интерфейсами с одним методом, что было бы довольно серьезным ограничением. Вместо этого были добавлены методы по умолчанию, позволяющие использовать более сложные интерфейсы.
Если вам нужно какое-то убедительное утверждение, которое
default
было введено из-за лямбда-выражений, обратите внимание, что в предложении соломенного человека проекта Lambda, сделанном Марком Рейнхольдом в 2009 году, «методы расширения» упоминаются как обязательная функция, которая должна быть добавлена для поддержки лямбда-выражений.Вот пример, демонстрирующий концепцию:
interface Operator { int operate(int n); default int inverse(int n) { return -operate(n); } } public int applyInverse(int n, Operator operator) { return operator.inverse(n); } applyInverse(3, n -> n * n + 7);
Я понимаю, очень надуманный, но должен показать, как
default
поддерживает лямбды. Посколькуinverse
это значение по умолчанию, при необходимости его можно легко заменить классом реализации.источник
В Java 8 представлена новая концепция, называемая методами по умолчанию. Методы по умолчанию - это те методы, которые имеют некоторую реализацию по умолчанию и помогают в развитии интерфейсов без нарушения существующего кода. Давайте посмотрим на пример:
public interface SimpleInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword default public void doSomeOtherWork(){ System.out.println("DoSomeOtherWork implementation in the interface"); } } class SimpleInterfaceImpl implements SimpleInterface{ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } /* * Not required to override to provide an implementation * for doSomeOtherWork. */ public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); } }
и вывод:
Реализация
DoSomeOtherWork в классе DoSomeOtherWork в интерфейсе
источник
В других ответах не учитывалась его роль в аннотациях. Еще в Java 1.5
default
ключевое слово появилось как средство для предоставления значения по умолчанию для поля аннотации.@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Processor { String value() default "AMD"; }
Его использование было перегружено с появлением Java 8, чтобы можно было определять метод по умолчанию в интерфейсах.
Еще кое-что было упущено: причина того, что объявление
default class MyClass {}
недействительно, связана с тем, как классы вообще объявляются . В языке нет положения, позволяющего использовать это ключевое слово. Однако он появляется для объявлений методов интерфейса .источник
Новая функция Java 8 ( методы по умолчанию ) позволяет интерфейсу предоставлять реализацию, если она помечена
default
ключевым словом.Например:
interface Test { default double getAvg(int avg) { return avg; } } class Tester implements Test{ //compiles just fine }
Тест интерфейса использует ключевое слово default, которое позволяет интерфейсу предоставлять реализацию метода по умолчанию без необходимости реализации этих методов в классах, использующих интерфейс.
Обратная совместимость: представьте, что ваш интерфейс реализован сотнями классов, изменение этого интерфейса заставит всех пользователей реализовать недавно добавленный метод, даже если он не является существенным для многих других классов, реализующих ваш интерфейс.
Факты и ограничения:
1-Может быть объявлен только в интерфейсе, а не в классе или абстрактном классе.
2-Должен предоставить тело
3-Он не считается общедоступным или абстрактным, как другие обычные методы, используемые в интерфейсе.
источник
Методы по умолчанию в интерфейсе позволяют нам добавлять новые функции, не нарушая старый код.
До Java 8, если новый метод был добавлен к интерфейсу, тогда все классы реализации этого интерфейса были обязаны переопределить этот новый метод, даже если они не использовали новую функциональность.
В Java 8 мы можем добавить реализацию по умолчанию для нового метода, используя
default
ключевое слово перед реализацией метода.Даже с анонимными классами или функциональными интерфейсами, если мы видим, что некоторый код можно использовать повторно, и мы не хотим определять одну и ту же логику повсюду в коде, мы можем написать их реализации по умолчанию и повторно использовать их.
пример
public interface YourInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword default public void doSomeOtherWork(){ System.out.println("DoSomeOtherWork implementation in the interface"); } } class SimpleInterfaceImpl implements YourInterface{ /* * Not required to override to provide an implementation * for doSomeOtherWork. */ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } /* * Main method */ public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); } }
источник
Очень хорошее объяснение можно найти в The Java ™ Tutorials , часть объяснения выглядит следующим образом:
Рассмотрим пример, в котором участвуют производители автомобилей с компьютерным управлением, которые публикуют стандартные отраслевые интерфейсы, описывающие, какие методы можно использовать для управления их автомобилями. Что, если эти производители автомобилей с компьютерным управлением добавят в свои машины новые функции, такие как полет? Этим производителям необходимо будет указать новые методы, которые позволят другим компаниям (например, производителям электронных приборов наведения) адаптировать свое программное обеспечение для летающих автомобилей. Где эти производители автомобилей объявят эти новые методы, связанные с полетами? Если они добавят их к своим исходным интерфейсам, программистам, которые реализовали эти интерфейсы, придется переписать свои реализации. Если они добавят их как статические методы, тогда программисты будут рассматривать их как служебные методы, а не как важные базовые методы.
Методы по умолчанию позволяют добавлять новые функции к интерфейсам ваших библиотек и обеспечивать двоичную совместимость с кодом, написанным для более старых версий этих интерфейсов.
источник
Методы по умолчанию позволяют добавлять новые функции в интерфейсы ваших приложений. Его также можно использовать для множественного наследования . В дополнение к методам по умолчанию вы можете определять статические методы в интерфейсах. Это упрощает организацию вспомогательных методов.
источник