Тема говорит о большинстве из этого - что является причиной того, что статические методы не могут быть объявлены в интерфейсе?
public interface ITest {
public static String test();
}
Приведенный выше код дает мне следующую ошибку (по крайней мере, в Eclipse): «Недопустимый модификатор для метода интерфейса ITest.test (); разрешены только public и abstract».
Ответы:
Здесь есть несколько проблем. Во-первых, это проблема объявления статического метода без его определения. Это разница между
и
Первое невозможно по причинам, которые упоминает Эспо : вы не знаете, какой класс реализации является правильным определением.
Java может позволить последнее; и на самом деле, начиная с Java 8, это так!
источник
static
методы вinterface
. Методы должны бытьpublic
.Причина, по которой у вас не может быть статического метода в интерфейсе, заключается в том, как Java разрешает статические ссылки. Java не будет беспокоиться о поиске экземпляра класса при попытке выполнить статический метод. Это связано с тем, что статические методы не зависят от экземпляра и, следовательно, могут выполняться прямо из файла класса. Учитывая, что все методы в интерфейсе являются абстрактными, ВМ должна была бы искать конкретную реализацию интерфейса, чтобы найти код, стоящий за статическим методом, чтобы он мог быть выполнен. Это противоречит принципу разрешения статического метода и может привести к несогласованности в языке.
источник
Я отвечу на ваш вопрос с примером. Предположим, у нас есть класс Math со статическим методом add. Вы бы назвали этот метод так:
Если бы Math был интерфейсом вместо класса, он не мог бы иметь никаких определенных функций. Поэтому говорить что-то вроде Math.add (2, 3) бессмысленно.
источник
Причина заключается в принципе дизайна, что Java не допускает множественного наследования. Проблема множественного наследования может быть проиллюстрирована на следующем примере:
Что произойдет, если вы вызовете Cx ()? Будет ли выполнен Ax () или Bx ()? Каждый язык с множественным наследованием должен решить эту проблему.
Интерфейсы позволяют в Java своего рода ограниченное множественное наследование. Чтобы избежать проблемы, описанной выше, им не разрешено иметь методы. Если мы посмотрим на ту же проблему с интерфейсами и статическими методами:
Та же проблема здесь, что произойдет, если вы вызовете Cx ()?
источник
A
содержатint x(int z);
и интерфейсB
содержатstring x(int x);
? Что означаетx(3)
в интерфейсе C?Статические методы не являются методами экземпляра. Там нет контекста экземпляра, поэтому реализовывать его из интерфейса имеет мало смысла.
источник
Теперь Java8 позволяет нам определять даже статические методы в интерфейсе.
Примечание: Методы в Интерфейсе по-прежнему являются публичными абстрактными по умолчанию, если мы явно не используем ключевые слова default / static, чтобы сделать их Методами по умолчанию и Статическими методами, соответственно.
источник
Там очень хороший и лаконичный ответ на ваш вопрос здесь . (Это показалось мне настолько простым и понятным способом объяснить это, что я хочу связать это отсюда.)
источник
Кажется, что статический метод в интерфейсе мог бы поддерживаться в Java 8 , ну, мое решение - просто определить их во внутреннем классе.
Та же техника также может быть использована в аннотациях:
Внутренний класс всегда должен быть доступен в форме,
Interface.fn...
вместо тогоClass.fn...
, чтобы избавиться от неоднозначной проблемы.источник
Интерфейс используется для полиморфизма, который применяется к объектам, а не к типам. Поэтому (как уже отмечалось) нет смысла иметь статический элемент интерфейса.
источник
Java 8 Изменил мир, вы можете иметь статические методы в интерфейсе, но это заставляет вас обеспечивать реализацию для этого.
}
источник
Недопустимая комбинация модификаторов: статические и абстрактные
Если член класса объявлен как статический, он может использоваться с именем класса, которое ограничено этим классом, без создания объекта.
Если член класса объявлен как абстрактный, вам нужно объявить класс абстрактным и предоставить реализацию абстрактного члена в его унаследованном классе (подклассе).
Вам необходимо предоставить реализацию абстрактному члену класса в подклассе, где вы собираетесь изменить поведение статического метода, также объявленного как абстрактный, который ограничен базовым классом, что не является правильным
источник
Так как статические методы не могут быть унаследованы. Так что нет смысла помещать его в интерфейс. Интерфейс - это контракт, которому должны следовать все его подписчики. Размещение статического метода в интерфейсе заставит подписчиков реализовать его. что теперь становится противоречащим факту, что статические методы не могут быть унаследованы.
источник
Например, Comparator имеет статический метод naturalOrder ().
Требование, чтобы интерфейсы не могли иметь реализации, также было смягчено. Интерфейсы теперь могут объявлять реализации метода «по умолчанию», которые похожи на обычные реализации с одним исключением: если вы наследуете как реализацию по умолчанию от интерфейса, так и обычную реализацию от суперкласса, реализация суперкласса всегда будет иметь приоритет.
источник
Возможно, пример кода поможет, я собираюсь использовать C #, но вы должны быть в состоянии следовать.
Давайте представим, что у нас есть интерфейс под названием IPayable
Теперь у нас есть два конкретных класса, которые реализуют этот интерфейс:
Теперь давайте представим, что у нас есть коллекция различных учетных записей, для этого мы будем использовать общий список типа IPayable
Теперь мы хотим заплатить $ 50,00 на все эти счета:
Итак, теперь вы видите, как интерфейсы невероятно полезны.
Они используются только для созданных объектов. Не на статических классах.
Если бы вы сделали оплату статичной, при циклическом просмотре списка IPayable в accountToPay не было бы способа выяснить, следует ли вызывать pay на BusinessAcount или CustomerAccount.
источник