Как JLS определяет термины «абстрактный метод», «конкретный метод» и «метод по умолчанию»? - PullRequest
5 голосов
/ 28 января 2020

Я видел "расходящиеся" определения терминов абстрактный метод , конкретный метод и метод по умолчанию в некоторых ответах StackOverflow.

Каковы реальные определения, приведенные в Java Спецификации языка? Пожалуйста, включите соответствующие вспомогательные ссылки JLS в ваш ответ.

Ответы [ 2 ]

9 голосов
/ 28 января 2020

Согласно JLS 8.4.3.1 :

"Объявление метода abstract представляет метод как член, предоставляя его подпись (§8.4.2), результат (§8.4.5), и бросает предложение, если таковое имеется (§8.4.6), но не обеспечивает реализацию (§8.4.7). Метод, который не является abstract, может упоминаться как Бетон метод."

Согласно JLS 9.4 :

" Метод по умолчанию - это метод экземпляра объявляется в интерфейсе с модификатором default. Его тело всегда представлено блоком, который обеспечивает реализацию по умолчанию для любого класса, реализующего интерфейс без переопределения метода. Методы по умолчанию отличаются от конкретных методов (§8.4.3.1), которые объявлены в классах, и из методов закрытого интерфейса , которые не наследуются и не переопределяются. "

Таким образом, согласно этой таксономии действительно 4 вида методов:

  • аннотация методы,
  • конкретные методы,
  • методы по умолчанию и
  • методы частного интерфейса

Обратите внимание, что JLS 8.4.3.1 не упоминает final или static в различии абстрактных и конкретных методов.

Эти модификаторы нельзя использовать с ключевым словом abstract. Это подразумевает, что методы static или final должны быть конкретными методами. Это усиливает определение конкретного метода 8.4.3.1.

4 голосов
/ 28 января 2020

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

Абстрактный метод определен в Java Спецификации языка (JLS) Раздел 8.4.3.1 как:

Абстрактный метод Объявление представляет метод в качестве члена, предоставляя его подпись (§8.4.2), результат (§8.4.5) и бросает предложение, если таковое имеется (§8.4.6), но не обеспечивает реализацию (§8.4.7) .

На практике абстрактный метод - это любой метод, сигнатура которого определена, но реализация не предусмотрена. Например, методы в интерфейсе и методы, квалифицированные ключевым словом abstract в абстрактном классе, оба являются абстрактными методами:

public interface Foo {
    void someAbstractMethod();
}

public abstract class Bar {

    public abstract someAbstractMethod();

    // ...

}

Конкретный метод

Согласно JLS Раздел 8.4 .3.1 , конкретный метод определяется как:

Метод, который не является абстрактным, может называться конкретным методом.

На практике этот метод означает любой метод, для которого предоставляется реализация:

public FooImpl implements Foo {

    @Override
    public void someAbstractMethod() {
        // ... some implementation ...
    }

}

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

Метод по умолчанию определен в JLS Раздел 9.4 :

Метод по умолчанию - это метод экземпляра, объявленный в интерфейсе с модификатором по умолчанию. Его тело всегда представлено блоком, который обеспечивает реализацию по умолчанию для любого класса, который реализует интерфейс без переопределения метода. Методы по умолчанию отличаются от конкретных методов (§8.4.3.1), которые объявлены в классах, и от методов закрытого интерфейса, которые не наследуются и не переопределяются.

В этом же разделе также добавлено:

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

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

Это не должно использоваться в качестве альтернативы абстрактным классам. Он предназначен для конкретной c цели и должен использоваться для этой цели.

На практике метод по умолчанию создается с использованием ключевого слова default:

public interface Foo {

    public default void someMethod() {
        // ... some default implementation ...
    }
}

Это значение по умолчанию Реализация может быть переопределена в конкретных подклассах:

public class FooImpl implements Foo {

    @Override
    public void someMethod() {
        // ... some overriding implementation ...
    }
}

Кроме того, согласно JLS Раздел 9.4.1.1 , доступна реализация метода по умолчанию (тело метода по умолчанию) в конкретных подклассах с использованием ключевого слова super, квалифицируемого по имени интерфейса:

Переопределенный метод по умолчанию может быть доступен с помощью выражения вызова метода (§15.12), которое содержит ключевое слово super qualified по имени суперинтерфейса.

Например:

public class FooImpl implements Foo {

    @Override
    public void someMethod() {
        Foo.super.someMethod();
    }
}

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

...