2014-12-14 4 views
18

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

Как я прочитал в соответствующем учебнике, классы, реализующие такой интерфейс, могут использовать свои статические методы. Но, у меня есть проблема, которая здесь, я показать его в более простом примере, чем то, что у меня есть

public interface Interface1{ 
    public static void printName(){ 
     System.out.println("Interface1"); 
    } 
} 

, когда я реализовать такой интерфейс

public class Class1 implements Interface1{ 
    public void doSomeThing() { 
     printName(); 
    } 
} 

я сталкиваюсь ошибка компиляции.

The method printName() is undefined for the type Class1 

В чем проблема?

+0

В вашем примере вы пытаетесь вызвать метод printName() ;. Ошибка компиляции, которую вы получаете, заключается в том, что в вашем классе Class1 не указан метод, называемый printName(); и компилятор пытается найти этот метод только в вашем классе. – foxt7ot

+3

* «Как я прочитал в связанном учебнике, классы, которые реализуют такой интерфейс, могут использовать свои статические методы». * Они могут, да - как могут классы, которые * не реализуют интерфейс. В обоих случаях вы должны квалифицировать вызов ('Interface1.printName();'). Если учебник подсказывает, что это должно работать, это просто неправильно. –

ответ

24

From the Java Language Specification,

Класс C наследует от своего прямого суперкласса все конкретные методы т (как статические, так и экземпляр) суперкласса, для которого все следующие условия:

  • [...]

Класс C наследует от своего прямого суперкласса и прямого суперинтерфейсов все абстрактно и по умолчанию (§9.4) методы т, для которых всех следующих условий:

  • [...]

класс не наследует статические методы от его суперинтерфейсов ,

Так что этот метод не наследуется.

Вы можете статически импортировать члену

import static com.example.Interface1.printName; 
... 
printName(); 

или использовать его с полным именем типа

com.example.Interface1.printName(); 

или импортировать тип, к которому printName принадлежит и вызывать его с коротким именем

import static com.example.Interface1; 
... 
Interface1.printName(); 
+1

Я искал и смотрел и смотрел в JLS для этого. Хороший. –

+15

В целом ...это отражает (преднамеренную) асимметрию между обработкой статических методов в классах и интерфейсах - статические методы в классах наследуются подтипами, но статические методы в интерфейсах не являются. Это было тщательно продуманное решение; в конце концов, путаница, подобная вопросу ОП, является естественным результатом введения таких асимметрий. Тем не менее, EG решительно ощущала, что существующее наследование статических методов в классах по существу является ошибкой дизайна, и что расширение его до интерфейсов создало бы множество запутанных краевых случаев с несколькими наследованиями для небольшой выгоды. –

+0

Два разных интерфейса могут объявлять статический метод с одинаковым именем. Вам не нужно использовать ПОЛНОСТЬЮ квалифицированное имя. 'Interface1.printName()' отлично работает, так как ключевое слово «реализует» по сути является импортом класса для большинства IDE. Статические методы (по крайней мере те, чьи реализации не содержатся в текущем классе) следует называть статически, т.е. 'MyClass.method()' везде, где это возможно, для удобочитаемости. –

Смежные вопросы