Почему я не могу объявить статические методы в интерфейсе?

148
задан skaffman 11 December 2010 в 21:19
поделиться

8 ответов

Здесь существует несколько проблем в действии. Первой является проблема объявления статического метода, не определяя его. Вот в чем разница между

public interface Foo {
  public static int bar();
}

и

public interface Foo {
  public static int bar() {
    ...
  }
}

, первое невозможно по причинам, что Espo упоминает: Вы не знаете, какой класс с реализацией является корректным определением.

Java мог позволять последнему; и на самом деле, начиная в Java 8, это делает!

85
ответ дан Community 11 December 2010 в 21:19
поделиться

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

7
ответ дан Ryan Farley 11 December 2010 в 21:19
поделиться

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

44
ответ дан Espo 11 December 2010 в 21:19
поделиться

Я отвечу на Ваш вопрос с примером. Предположим, что у нас был Математический класс со статическим методом, добавляют. Вы назвали бы этот метод как так:

Math.add(2, 3);

, Если Математика была интерфейсом вместо класса, она не могла бы иметь никаких определенных функций. По сути, высказывание чего-то как Math.add (2, 3) не имеет никакого смысла.

18
ответ дан Kyle Cronin 11 December 2010 в 21:19
поделиться

Интерфейс используется для полиморфизма, который относится к Объектам, не типам. Поэтому (как уже отмечено) не имеет никакого смысла иметь статического интерфейсного участника.

2
ответ дан Rob Cooper 11 December 2010 в 21:19
поделиться

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

-2
ответ дан FlySwat 11 December 2010 в 21:19
поделиться

Причина находится в принципе разработки, тот 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 ()?

11
ответ дан Mnementh 11 December 2010 в 21:19
поделиться

Существует очень хороший и краткий ответ на Ваш вопрос здесь . (Это показалось мне таким приятно простым способом объяснить это, что я хочу связать его отсюда.)

4
ответ дан Community 12 December 2010 в 07:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: