Какова цель ключевого слова по умолчанию в Java?

Интерфейс в 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 (без модификатора доступа)?

Ответ 1

Это новая функция Java 8, которая позволяет interface обеспечить реализацию. Описан на Java 8 JLS-13.5.6. Объявление метода интерфейса, которое читает (частично)

Добавление метода default или изменение метода от abstract до default не нарушает совместимость с ранее существовавшими двоичными файлами, но может вызвать IncompatibleClassChangeError, если ранее существовавший двоичный код пытается вызвать метод. Эта ошибка возникает, если квалификационный тип T является подтипом двух интерфейсов, I и J, где оба I и J объявляют метод default с той же сигнатурой и результатом и ни I, ни J не является дополнительным элементом другого.

Что нового в JDK 8 (частично)

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

Ответ 2

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

Если вам нужно какое-то убедительное утверждение о том, что default был введен из-за лямбд, отметьте, что предложение соломенного оферты Project 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 является значением по умолчанию, оно может быть легко переопределено реализующим классом, если требуется.

Ответ 3

В 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 в интерфейсе

Ответ 4

Что-то, что было упущено в других ответах, было его ролью в аннотациях. Еще в Java 1.5 ключевое слово по default появилось как средство для предоставления значения по умолчанию для поля аннотации.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Processor {
    String value() default "AMD";
}

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

Что-то еще, что было упущено: причина, default class MyClass {} недопустим, объясняется тем, как объявляются классы вообще. На этом языке нет положения, позволяющего отображать это ключевое слово. Тем не менее, он появляется для объявлений метода интерфейса.

Ответ 5

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

Например:

interface Test {
    default double getAvg(int avg) {
        return avg;
    }
}
class Tester implements Test{
 //compiles just fine
}

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

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

Факты и ограничения:

1-May только объявляется внутри интерфейса, а не внутри класса или абстрактного класса.

2 - должен обеспечить тело

3 - Это не предполагается публичным или абстрактным, как другие обычные методы, используемые в интерфейсе.

Ответ 6

Очень хорошее объяснение содержится в Учебные пособия Java ™, часть объяснения такова:

Рассмотрим пример, в котором участвуют производители компьютеров с компьютерным управлением, которые публикуют отраслевые интерфейсы, которые описывают, какие методы могут быть использованы для управления их автомобилями. Что делать, если эти управляемые компьютером автопроизводители добавляют новые функции, такие как полет, к своим автомобилям? Этим производителям необходимо будет указать новые методы, позволяющие другим компаниям (таким как производители электронных накладных инструментов) адаптировать свое программное обеспечение к летательным аппаратам. Где эти автопроизводители объявят эти новые методы, связанные с полетом? Если они добавят их в свои исходные интерфейсы, тогда программистам, которые реализовали эти интерфейсы, придется переписать их реализации. Если они добавят их как статические методы, тогда программисты будут рассматривать их как полезные методы, а не как основные, основные методы.

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

Ответ 7

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

Ответ 8

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

До 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();
      }
   }