주제는 그 대부분을 말합니다-인터페이스에서 정적 메소드를 선언 할 수 없다는 이유는 무엇입니까?
public interface ITest {
public static String test();
}
위 코드는 적어도 Eclipse에서 다음과 같은 오류를 발생시킵니다. “인터페이스 메소드 ITest.test ()의 잘못된 수정 자; 공개 및 요약 만 허용됩니다.”
답변
여기에 몇 가지 문제가 있습니다. 첫 번째는 정적 메소드를 정의하지 않고 선언하는 문제입니다. 이것은 차이점입니다
public interface Foo {
public static int bar();
}
과
public interface Foo {
public static int bar() {
...
}
}
첫 번째는 Espo가 언급 한 이유로 불가능 합니다. 어떤 구현 클래스가 올바른 정의인지 모릅니다.
자바 는 후자를 허용 할 수있다. 실제로 Java 8부터 시작합니다!
답변
인터페이스에 정적 메소드를 가질 수없는 이유는 Java가 정적 참조를 분석하는 방식에 있습니다. Java는 정적 메소드를 실행하려고 할 때 클래스의 인스턴스를 찾지 않습니다. 정적 메소드는 인스턴스에 종속되지 않으므로 클래스 파일에서 직접 실행될 수 있기 때문입니다. 인터페이스의 모든 메소드가 추상적이라는 점에서 VM은 정적 메소드 뒤의 코드를 찾아서 실행될 수 있도록 인터페이스의 특정 구현을 찾아야합니다. 그러면 정적 메소드 분석이 작동하는 방식과 모순되며 언어에 불일치가 발생합니다.
답변
예를 들어 질문에 대답하겠습니다. 정적 메소드 add를 가진 Math 클래스가 있다고 가정하십시오. 이 방법을 다음과 같이 호출합니다.
Math.add(2, 3);
Math가 클래스 대신 인터페이스 인 경우 정의 된 함수를 가질 수 없습니다. 따라서 Math.add (2, 3)과 같은 것을 말하면 의미가 없습니다.
답변
그 이유는 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 ()를 호출하면 어떻게됩니까?
답변
정적 메소드는 인스턴스 메소드가 아닙니다. 인스턴스 컨텍스트가 없으므로 인터페이스에서 구현하는 것이 의미가 없습니다.
답변
이제 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
}
}
참고 : 키워드를 default / static 키워드로 명시 적으로 사용하여 기본 메소드 및 정적 메소드를 지정하지 않으면 인터페이스의 메소드는 기본적으로 여전히 공개 추상입니다.