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

голоса
143

Тема говорит большинство из них - то, что является причиной того, что статические методы не могут быть объявлены в интерфейсе?

public interface ITest {
    public static String test();
}

Приведенный выше код дает мне следующее сообщение об ошибке (в Eclipse, по крайней мере): «Illegal модификатор для метода интерфейса ITest.test (); только общественности и аннотация разрешены».

Задан 22/08/2008 в 06:16
источник пользователем
На других языках...                            


13 ответов

голоса
80

Есть несколько вопросов, в игре здесь. Первым из них является вопрос об объявлении статического метода без его определения. Это разница между

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

а также

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

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

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

Ответил 22/08/2008 d 15:29
источник пользователем

голоса
42

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

Ответил 22/08/2008 d 06:20
источник пользователем

голоса
20

Я отвечу на ваш вопрос. Например, Предположим, что мы имели класс Math статический метод оных. Вы могли бы назвать этот метод следующим образом:

Math.add(2, 3);

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

Ответил 22/08/2008 d 06:19
источник пользователем

голоса
11

Причина заключается в разработке принципе, то, что Java не допускает множественное наследование. Проблема с множественного наследования можно проиллюстрировать следующим примером:

public class A {
   public method x() {...}
}
public class B {
   public method x() {...}
}
public class C extends A, B { ... }

Теперь, что произойдет, если вы звоните Cx ()? Будет Ax () или Bx () казнили? Каждый язык множественного наследования должен решить эту проблему.

Интерфейсы позволяют в Java какое-то ограниченное множественного наследования. Чтобы избежать этой проблемы выше, они не могут иметь методы. Если мы посмотрим на те же задачи с интерфейсами и статическими методами:

public interface A {
   public static method x() {...}
}
public interface B {
   public static method x() {...}
}
public class C implements A, B { ... }

Такая же проблема здесь, то, что произойдет, если вы звоните Cx ()?

Ответил 26/09/2008 d 09:48
источник пользователем

голоса
7

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

Ответил 22/08/2008 d 06:18
источник пользователем

голоса
5

Теперь Java8 позволяет определить даже статические методы в интерфейсе.

interface X {
    static void foo() {
       System.out.println("foo");
    }
}

class Y implements X {
    //...
}

public class Z {
   public static void main(String[] args) {
      X.foo();
      // Y.foo(); // won't compile because foo() is a Static Method of X and not Y
   }
}

Примечание: методы в интерфейсе по-прежнему общественности абстрактные по умолчанию, если мы не будем явно использовать ключевые слова по умолчанию / статический, чтобы сделать их Защитнику методы и статические методы соответственно.

Ответил 28/03/2014 d 12:19
источник пользователем

голоса
4

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

Ответил 06/02/2009 d 13:19
источник пользователем

голоса
3

Кажется , статический метод в интерфейсе может поддерживаться в Java 8 , ну, мое решение просто определить их во внутреннем классе.

interface Foo {
    // ...
    class fn {
        public static void func1(...) {
            // ...
        }
    }
}

Же метод может быть также использован в аннотации:

public @interface Foo {
    String value();

    class fn {
        public static String getValue(Object obj) {
            Foo foo = obj.getClass().getAnnotation(Foo.class);
            return foo == null ? null : foo.value();
        }
    }
}

Внутренний класс всегда должен быть доступен в форме Interface.fn...вместо Class.fn..., то вы можете избавиться от неоднозначной проблемы.

Ответил 17/09/2013 d 05:09
источник пользователем

голоса
2

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

Ответил 22/08/2008 d 06:27
источник пользователем

голоса
1

Java 8 изменил мир, который вы можете иметь статические методы в интерфейсе, но это заставляет вас обеспечить реализацию для этого.

public interface StaticMethodInterface {
public static int testStaticMethod() {
    return 0;
}

/**
 * Illegal combination of modifiers for the interface method
 * testStaticMethod; only one of abstract, default, or static permitted
 * 
 * @param i
 * @return
 */
// public static abstract int testStaticMethod(float i);

default int testNonStaticMethod() {
    return 1;
}

/**
 * Without implementation.
 * 
 * @param i
 * @return
 */
int testNonStaticMethod(float i);

}

Ответил 05/02/2016 d 09:49
источник пользователем

голоса
0

Так как статические методы не могут наследоваться. Так что никакой пользы не помещая его в интерфейсе. Интерфейс в основном контракт, который все абоненты должны следовать. Размещение статического метода в интерфейсе заставит абонентов реализовать его. который теперь становится противоречивым тот факт, что статические методы не могут наследоваться.

Ответил 15/12/2013 d 06:00
источник пользователем

голоса
0

Нелегальная комбинации модификаторов: статическая и абстрактная

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

Если член класса объявлен как абстрактный, вам нужно объявить класс как абстрактный, и вы должны обеспечить реализацию абстрактного элемента в его унаследовали класса (Sub-Class).

Вы должны обеспечить реализацию для абстрактного члена класса в суб-классе, где вы собираетесь изменить поведение статического метода, также объявлен как абстрактный, который является прикован к базовому классу, который не является правильным

Ответил 02/10/2013 d 11:32
источник пользователем

голоса
-2

Возможно, пример кода поможет, я буду использовать 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-х в accountsToPay не было бы никакого способа, чтобы выяснить, если он должен вызвать платить по BusinessAcount или УЧЁТНАЯЗАПИСЬ.

Ответил 22/08/2008 d 06:35
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more