Здесь существует несколько проблем в действии. Первой является проблема объявления статического метода, не определяя его. Вот в чем разница между
public interface Foo {
public static int bar();
}
и
public interface Foo {
public static int bar() {
...
}
}
, первое невозможно по причинам, что Espo упоминает: Вы не знаете, какой класс с реализацией является корректным определением.
Java мог позволять последнему; и на самом деле, начиная в Java 8, это делает!
Статические методы не являются методами экземпляра. Нет никакого контекста экземпляра, поэтому для реализации его от интерфейса имеет мало смысла.
Причина, почему у Вас не может быть статического метода в интерфейсе, заключается в том, как статические ссылки твердости Java. Java не потрудится искать экземпляр класса при попытке выполнить статический метод. Это вызвано тем, что статические методы не являются зависимым экземпляра и следовательно могут быть выполнены прямо из файла класса. Учитывая, что все методы в интерфейсе абстрактны, VM должен был бы искать конкретную реализацию интерфейса для нахождения кода позади статического метода так, чтобы это могло быть выполнено. Это тогда противоречит, как разрешение статического метода работает и ввело бы несоответствие в язык.
Я отвечу на Ваш вопрос с примером. Предположим, что у нас был Математический класс со статическим методом, добавляют. Вы назвали бы этот метод как так:
Math.add(2, 3);
, Если Математика была интерфейсом вместо класса, она не могла бы иметь никаких определенных функций. По сути, высказывание чего-то как Math.add (2, 3) не имеет никакого смысла.
Интерфейс используется для полиморфизма, который относится к Объектам, не типам. Поэтому (как уже отмечено) не имеет никакого смысла иметь статического интерфейсного участника.
Возможно, пример кода помог бы, я собираюсь использовать C#, но необходимо быть в состоянии следовать вперед.
Позволяет, притворяются, что у нас есть интерфейс, названный IPayable
public interface IPayable
{
public Pay(double amount);
}
Теперь, у нас есть два реальных класса, которые реализуют этот интерфейс:
public class BusinessAccount : IPayable
{
public void Pay(double amount)
{
//Logic
}
}
public class CustomerAccount : IPayable
{
public void Pay(double amount)
{
//Logic
}
}
Теперь, позволяет, притворяются, что у нас есть набор различных учетных записей, чтобы сделать это мы будем использовать универсальный список IPayable
List<IPayable> accountsToPay = new List<IPayable>();
accountsToPay.add(new CustomerAccount());
accountsToPay.add(new BusinessAccount());
типа Теперь, мы хотим зачислить 50,00$ на все те счета:
foreach (IPayable account in accountsToPay)
{
account.Pay(50.00);
}
Поэтому теперь Вы видите, как интерфейсы невероятно полезны.
Они используются на инстанцированных объектах только. Не на статических классах.
, Если Вы сделали плату статичной, когда цикличное выполнение через IPayable's в accountsToPay там не будет никаким способом выяснить, должно ли это назвать плату на BusinessAcount или CustomerAccount.
Причина находится в принципе разработки, тот Java не позволяет множественное наследование. Проблема со множественным наследованием может быть проиллюстрирована следующим примером:
public class A {
public method x() {...}
}
public class B {
public method x() {...}
}
public class C extends A, B { ... }
Теперь, что происходит, если Вы называете C.x ()? Будет A.x () или B.x () выполнен? Каждый язык со множественным наследованием должен решить эту проблему.
Интерфейсы позволяют в Java своего рода ограниченное множественное наследование. Для предотвращения проблемы выше им не позволяют иметь методы. Если мы смотрим на ту же проблему с интерфейсами и статическими методами:
public interface A {
public static method x() {...}
}
public interface B {
public static method x() {...}
}
public class C implements A, B { ... }
Та же проблема здесь, что происходит, если Вы называете C.x ()?
Существует очень хороший и краткий ответ на Ваш вопрос здесь . (Это показалось мне таким приятно простым способом объяснить это, что я хочу связать его отсюда.)