Может ли метод интерфейса иметь тело?
Я знаю, что интерфейс подобен абстрактному классу с чистотой 100%. Таким образом, в нем не может быть реализации метода. Но я увидел странный код. Кто-нибудь может объяснить это?
Фрагмент кода:
interface Whoa {
public static void doStuff() {
System.out.println("This is not default implementation");
}
}
EDIT:
Моя IDE - это идея Intellij 13.1. SDK проекта - java 7 и 1.7.0_25 > . В IDE не отображается какая-либо ошибка компилятора. Но, когда я компилирую код в командной строке, я получаю следующее сообщение.
Whoa.java:2: error: modifier static not allowed here
public static void doStuff() {
^
Ответы
Ответ 1
От Java 8 вы можете определять статические методы в интерфейсах в дополнение к методам по умолчанию.
-
Статический метод - это метод, который связан с классом, в котором он определен, а не с каким-либо объектом. Каждый экземпляр класса использует свои статические методы.
-
Это облегчает вам организацию вспомогательных методов в ваших библиотеках; вы можете хранить статические методы, специфичные для интерфейса в одном и том же интерфейсе, а не в отдельном классе.
-
В следующем примере определяется статический метод, который извлекает объект ZoneId
, соответствующий идентификатору часового пояса; он использует часовой пояс системы по умолчанию, если нет объекта ZoneId
, соответствующего данному идентификатору. (В результате вы можете упростить метод getZonedDateTime
)
Вот код:
public interface TimeClient {
// ...
static public ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default public ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
См. также
Ответ 2
Это возможно только в Java 8. В Java 7 Спецификация языка §9.4 в нем явно указано:
Это ошибка времени компиляции, если объявленный в интерфейсе метод объявлен статическим, поскольку статические методы не могут быть абстрактными.
Итак, в Java 7 статические методы в интерфейсах не могут существовать.
Если вы перейдете к Java 8 Спецификация языка §9.4.3, вы увидите, что он говорит:
Статический метод также имеет тело блока, которое обеспечивает реализацию метода.
Поэтому он явно заявляет, что в Java 8 они могут существовать.
Я даже пытался запустить ваш точный код в Java 1.7.0_45, но он дал мне ошибку "модификатор static не разрешен здесь".
Вот цитата непосредственно из учебника Java 8, Способы по умолчанию (Изучение языка Java > Интерфейсы и наследование):
Статические методы
В дополнение к методам по умолчанию вы можете определить статические методы в интерфейсы. (Статический метод - это метод, связанный с класс, в котором он определен, а не какой-либо объект. каждый экземпляр класса разделяет его статические методы.) Это упрощает для организации вспомогательных методов в ваших библиотеках; вы можете сохранить статические методы, специфичные для интерфейса в одном и том же интерфейсе, чем в отдельном классе. В следующем примере определяется статический метод, который извлекает объект ZoneId
, соответствующий времени идентификатор зоны; он использует часовой пояс системы по умолчанию, если нет ZoneId
объект, соответствующий данному идентификатору. (В результате, вы можете упростить метод getZonedDateTime
):
public interface TimeClient {
// ...
static public ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +
"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default public ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
Как и статические методы в классах, вы указываете, что определение метода в интерфейсе - статический метод с ключевым словом static
. начало подписи метода. Все объявления методов в интерфейс, включая статические методы, неявно public
, поэтому вы может опустить модификатор public
.
Ответ 3
Для java версии 7 или ниже, аналогично функционально вы можете добиться, используя вложенный класс, объявленный внутри тела интерфейса. и этот вложенный класс реализует внешний интерфейс.
Пример:
interface I1{
public void doSmth();
class DefaultRealizationClass implements I1{
@Override
public void doSmth() {
System.out.println("default realization");
}
}
}
Как мы используем его в нашем коде?
class MyClass implements I1{
@Override
public void doSmth() {
new I1.DefaultRealizationClass().doSmth();
}
}
Поэтому реализация по умолчанию инкапсулирована внутри интерфейса.
Ответ 4
Для Java версии 9 в дополнение к статическим и стандартным методам интерфейс теперь также может содержать частные методы, что может быть очень полезно:
public interface DemoInterface {
void ordinaryInterfaceMethod();
default void method1() {
print();
}
default void method2() {
print();
}
private void print() {
System.out.println("Hello World!");
}
}
Частный метод не является частью публичного API, открытого интерфейсом и может совместно использовать общие функции.