답변:
인터페이스는 상호 작용 계약 만 지정하고 구현 세부 정보는 지정하지 않기 때문에 동작이나 상태를 가질 수 없습니다. '행동 없음'은 메서드 / 생성자 본문 또는 정적 / 인스턴스 초기화 블록을 허용하지 않음으로써 강제됩니다. '상태 없음'은 정적 최종 필드 만 허용하여 적용됩니다. 따라서 클래스는 상태 (정적 상태)를 가질 수 있지만 인스턴스 상태는 인터페이스에 의해 유추되지 않습니다.
BTW : Java의 상수는 정적 최종 필드로 정의됩니다 (일반적으로 이름은 UPPER_CASE_AND_UNDERSCORES를 사용함).
static final
, const
자바에서 얻을 수있는 것처럼 실제 (실제 C / C ++)에 가까운 인스턴스 필드를 강제로 선택합니다 . 불행히도 이것은 암시 적이며 비전문가에게 혼란을 줄 수 있습니다. (난 그냥 그들이 것을 깨달았다 static
내가 의도하지 않은 행동을 관찰하기 때문에 나는 그들이 것을 배웠습니다. final
이 대답에서만.)
존재 이유 final
최종적으로 정의되지 않은 모든 구현은 필드 값을 변경할 수 있습니다. 그런 다음 그들은 구현의 일부가 될 것입니다. 인터페이스는 구현이없는 순수한 사양입니다.
존재 이유 static
정적 인 경우 개체 나 개체의 런타임 유형이 아닌 인터페이스에 속합니다.
여기에 몇 가지 요점이 있습니다.
인터페이스의 필드가 암시 적으로 static final이라고해서 컴파일 타임 상수이거나 변경 불가능한 것도 아닙니다. 예를 들어 정의 할 수 있습니다.
interface I { String TOKEN = SomeOtherClass.heavyComputation(); JButton BAD_IDEA = new JButton("hello"); }
(주석 정의 내에서이 작업을 수행 하면 위의 내용이 실제로 정적 초기화 프로그램으로 컴파일된다는 사실과 관련하여 javac 를 혼동 할 수 있습니다 .)
또한 이러한 제한의 이유는 기술적 인 것보다 문체 적이며 많은 사람들이이 제한이 완화되기를 원합니다 .
필드는 추상적 일 수 없기 때문에 정적이어야합니다 (메소드처럼). 추상적 일 수 없기 때문에 구현자는 필드의 다른 구현을 논리적으로 제공 할 수 없습니다.
필드는 여러 구현자가 액세스 할 수 있으므로 변경 가능할 수 있으므로 (동기화로) 문제가 될 수 있기 때문에 필드는 최종적이어야합니다. 또한 다시 구현 (숨김)되는 것을 방지합니다.
그냥 내 생각.
public static
않은 필드가 있으면 final
findbugs가 (올바르게!) 불평합니다.
필자는 필드가 최종적이어야한다는 요구 사항이 지나치게 제한적이고 Java 언어 디자이너의 실수라고 생각합니다. 인터페이스 유형의 객체에 대한 작업을 수행하는 데 필요한 구현에서 상수를 설정해야하는 경우, 예를 들어 트리 처리와 같은 경우가 있습니다. 구현 클래스에서 코드 경로를 선택하는 것은 어려운 일입니다. 내가 사용하는 해결 방법은 인터페이스 함수를 정의하고 리터럴을 반환하여 구현하는 것입니다.
public interface iMine {
String __ImplementationConstant();
...
}
public class AClass implements iMine {
public String __ImplementationConstant(){
return "AClass value for the Implementation Constant";
}
...
}
public class BClass implements iMine {
public String __ImplementationConstant(){
return "BClass value for the Implementation Constant";
}
...
}
그러나이 구문을 사용하는 것이 더 간단하고 명확하며 비정상적인 구현 가능성이 적습니다.
public interface iMine {
String __ImplementationConstant;
...
}
public class AClass implements iMine {
public static String __ImplementationConstant =
"AClass value for the Implementation Constant";
...
}
public class BClass implements iMine {
public static String __ImplementationConstant =
"BClass value for the Implementation Constant";
...
}
사양, 계약 ... 필드 액세스를위한 기계 명령어는 객체 주소와 필드 오프셋을 사용합니다. 클래스는 많은 인터페이스를 구현할 수 있으므로이 인터페이스를 확장하는 모든 클래스에서 동일한 오프셋을 갖도록 비 최종 인터페이스 필드를 만들 수있는 방법이 없습니다. 따라서 필드 액세스를위한 다른 메커니즘이 구현되어야합니다. 하나가 아닌 두 개의 메모리 액세스 (필드 오프셋 가져 오기, 필드 값 가져 오기)와 가상 필드 테이블의 종류 (가상 메소드 테이블의 아날로그)를 유지합니다. 기존 항목 (방법)을 통해 쉽게 시뮬레이션 할 수있는 기능을 위해 jvm을 복잡하게 만들고 싶지는 않은 것 같습니다.
스칼라에서는 인터페이스에 필드를 가질 수 있지만 내부적으로는 위에서 설명한대로 (메서드로) 구현됩니다.