인터페이스 변수가 디폴트로는 스태틱하고 최종적인 이유는 무엇입니까?
Java에서 인터페이스 변수가 디폴트로 스태틱하고 최종적인 이유는 무엇입니까?
필립 쇼의 Java 인터페이스 설계에 관한 FAQ에서 다음 내용을 참조해 주십시오.
Java 인터페이스는 그 자체로 인스턴스화할 수 없기 때문에 인터페이스 변수는 스태틱합니다.인스턴스가 존재하지 않는 스태틱콘텍스트에서 변수 값을 할당해야 합니다.최종 수식자는 인터페이스 변수에 할당된 값이 프로그램 코드로 재할당할 수 없는 진정한 상수임을 확인합니다.
public: 인터페이스에 존재하는 메서드와 마찬가지로 모든 클래스에 대한 접근성 확보
static: 인터페이스에는 오브젝트를 포함할 수 없기 때문에 interfaceName.variableName을 사용하여 오브젝트를 참조하거나 이를 구현하는 클래스의 variableName을 직접 참조할 수 있습니다.
final: 상수로 만듭니다.2개의 클래스가 같은 인터페이스를 실장하고, 그 양쪽 모두에 값을 변경할 수 있는 권한을 부여하면 var의 현재 값에서 경합이 발생하기 때문에 초기화는 1회만 허용됩니다.
또, 이러한 수식어는 모두 인터페이스에 대해서 암묵적인 것이므로, 어느쪽도 지정할 필요는 없습니다.
인터페이스에는 직접 오브젝트가 없기 때문에 클래스/인터페이스를 사용하는 방법밖에 없습니다.따라서 인터페이스 변수가 존재할 경우 스태틱해야 합니다.그렇지 않으면 외부에서는 전혀 액세스 할 수 없습니다.정적이기 때문에 값을 1개만 유지할 수 있으며, 이를 구현하는 클래스는 값을 변경할 수 있으므로 모든 것이 엉망이 됩니다.
따라서 인터페이스 변수가 조금이라도 존재한다면 암묵적으로 스태틱하고 최종적이며 명백히 퍼블릭한 변수가 됩니다.
(이것은 철학적인 대답이 아니라 실용적인 답변입니다.)의 요건static
다른 사람들이 대답한 수식어는 명백하다.기본적으로 인터페이스를 인스턴스화할 수 없기 때문에 해당 필드에 액세스하는 유일한 방법은 클래스 필드를 만드는 것입니다.static
.
이면에 있는 이유interface
필드는 자동으로 지정됩니다.final
(임의) 다른 구현에 의해 인터페이스 변수의 값이 잘못 변경되어 다른 구현의 동작에 영향을 주는 것을 방지하기 위한 것입니다.다음 시나리오를 상상해 보십시오.interface
속성이 명시적으로 바뀌지는 않았습니다.final
Java:
public interface Actionable {
public static boolean isActionable = false;
public void performAction();
}
public NuclearAction implements Actionable {
public void performAction() {
// Code that depends on isActionable variable
if (isActionable) {
// Launch nuclear weapon!!!
}
}
}
자, 이제, 만약 다른 클래스가 다른 클래스에서Actionable
인터페이스 변수 상태를 변경합니다.
public CleanAction implements Actionable {
public void performAction() {
// Code that can alter isActionable state since it is not constant
isActionable = true;
}
}
이러한 클래스가 클래스 로더에 의해 단일 JVM 내에 로드되는 경우,NuclearAction
다른 클래스의 영향을 받을 수 있습니다.CleanAction
이 경우,performAction()
다음에 호출됩니다.CleanAction
는 (같은 스레드 또는 그 외의) 실행되며, 이 경우 (대부분의 경우) 치명적일 수 있습니다.
각각의 구현 방법을 모르기 때문에interface
이 변수들을 사용하려고 합니다.이 변수들은 암묵적으로final
.
그 외의 것은 실장의 일부이며, 인터페이스는 실장을 포함할 수 없기 때문입니다.
public interface A{
int x=65;
}
public interface B{
int x=66;
}
public class D implements A,B {
public static void main(String[] a){
System.out.println(x); // which x?
}
}
여기 해결책이 있습니다.
System.out.println(A.x); // done
이것이 인터페이스 변수가 스태틱한 이유 중 하나라고 생각합니다.
인터페이스 내부에서 변수를 선언하지 마십시오.
static - 인터페이스에는 인스턴스를 사용할 수 없기 때문입니다.그리고 최종 - 변경할 필요가 없기 때문입니다.
이유:
Static
: 인터페이스의 오브젝트를 가질 수 없기 때문에 오브젝트레벨 멤버 변수 사용을 피하고 클래스레벨 변수(스태틱)를 사용해야 합니다.
Final
: 변수에 애매한 값을 갖지 않도록 합니다(다이아몬드 문제 - 다중 상속).
또, 설명서에 의하면, 인터페이스는 계약서일 뿐, 실장이 아닙니다.
참조:퀴라에 대한 아비섹 자인의 대답
Java는 인터페이스에서 추상 변수 및/또는 생성자 정의를 허용하지 않습니다.솔루션:다음과 같이 추상 클래스를 확장하기 위한 인터페이스와 구현 사이에 추상 클래스를 설정하기만 하면 됩니다.
public interface IMyClass {
void methodA();
String methodB();
Integer methodC();
}
public abstract class myAbstractClass implements IMyClass {
protected String varA, varB;
//Constructor
myAbstractClass(String varA, String varB) {
this.varA = varA;
this.varB = VarB;
}
//Implement (some) interface methods here or leave them for the concrete class
protected void methodA() {
//Do something
}
//Add additional methods here which must be implemented in the concrete class
protected abstract Long methodD();
//Write some completely new methods which can be used by all subclasses
protected Float methodE() {
return 42.0;
}
}
public class myConcreteClass extends myAbstractClass {
//Constructor must now be implemented!
myClass(String varA, String varB) {
super(varA, varB);
}
//All non-private variables from the abstract class are available here
//All methods not implemented in the abstract class must be implemented here
}
나중에 다른 인터페이스와 함께 추상 클래스를 구현하지 않을 경우 인터페이스 없이 추상 클래스를 사용할 수도 있습니다.추상 클래스의 인스턴스를 만들 수 없으므로 먼저 확장해야 합니다.
('protected' 키워드는 확장 클래스만 이러한 메서드 및 변수에 액세스할 수 있음을 의미합니다).
스파이로
Interface : 시스템 요건 서비스.
인터페이스에서는 변수는 기본적으로 public, static, final 액세스 수식자에 의해 할당됩니다.이유:
public : 인터페이스가 다른 패키지에 배치되는 경우가 있습니다.따라서 프로젝트 내 어디에서나 변수에 액세스해야 합니다.
static : 이러한 불완전한 클래스는 개체를 만들 수 없습니다.따라서 프로젝트에서는 오브젝트 없이 변수에 액세스하여interface_filename.variable_name
final : 1개의 인터페이스가 여러 클래스에 의해 실장되어 모든 클래스가 인터페이스 변수에 대한 접근과 갱신을 시도한다고 가정합니다.따라서 데이터 변경에 일관성이 없고 다른 모든 클래스에 영향을 미칩니다.따라서 액세스 수식자를 final로 선언해야 합니다.
인터페이스는 두 당사자 간의 계약으로, 불변하며, 돌에 새겨지기 때문에 최종적입니다.계약별 설계를 참조하십시오.
인Java
인터페이스에서는 인스턴스 변수를 선언할 수 없습니다.인터페이스에서 선언된 변수를 인스턴스 변수로 사용하면 컴파일 시간 오류가 반환됩니다.
상수 변수를 선언할 수 있습니다.static final
인스턴스 변수와는 다릅니다.
인터페이스는 어떤 클래스에 의해서도 실장할 수 있습니다.그 값이 실장 클래스 중 하나에 의해서 변경되면, 다른 실장 클래스에 대해서 오해가 생깁니다.인터페이스는 기본적으로는 서로 다른2개의 코어화된 entity.so을 조합하는 참조입니다.따라서 인터페이스를 인스턴스화할 수 없기 때문에 인터페이스 내부의 선언 변수는 암묵적으로 최종 변수이며 스태틱 변수이기도 합니다.
인터페이스가 정의되어 있고 다른 클래스에서 구현되어 있는 웹 응용 프로그램을 생각해 보십시오.변수에 액세스하기 위한 인터페이스 인스턴스를 생성할 수 없으므로 static 키워드를 지정해야 합니다.이 값은 정적이기 때문에 값이 변경되면 해당 값을 구현한 다른 인스턴스에 반영됩니다.이를 방지하기 위해 최종적인 것으로 정의합니다.
Eclipse에서 방금 시도한 인터페이스 변수는 기본적으로 최종 변수이므로 변경할 수 없습니다.부모 계층과 비교했을 때 변수는 확실히 바뀔 수 있습니다. 왜일까요?제 관점에서는 수업의 변수는 아이들이 물려받을 속성으로, 아이들이 실제 필요에 따라 바꿀 수 있습니다.반대로 인터페이스는 Atribute가 아닌 동작만을 정의합니다.인터페이스에 변수를 넣는 유일한 이유는 해당 인터페이스와 관련된 Const로 변수를 사용하기 위해서입니다.단, 다음 발췌에 따르면 이는 좋은 방법이 아닙니다.
"인터페이스의 상수를 배치하는 것은 Java 초기에는 일반적인 기술이었지만, 지금은 인터페이스가 데이터가 아닌 객체가 제공하는 서비스를 다루어야 하기 때문에 많은 사람들이 이것을 인터페이스의 불쾌한 사용으로 간주하고 있습니다.또한 클래스에서 사용되는 상수는 일반적으로 구현 세부 사항이지만 인터페이스에 배치하면 클래스의 퍼블릭 API로 승격됩니다."
저도 잡음을 넣거나 전혀 차이가 나지 않게 하려고 노력했습니다.코드는 다음과 같습니다.
public interface Addable {
static int count = 6;
public int add(int i);
}
public class Impl implements Addable {
@Override
public int add(int i) {
return i+count;
}
}
public class Test {
public static void main(String... args) {
Impl impl = new Impl();
System.out.println(impl.add(4));
}
}
언급URL : https://stackoverflow.com/questions/2430756/why-are-interface-variables-static-and-final-by-default
'programing' 카테고리의 다른 글
vuejs에서 다른 모달 표시 후 모달은 자동으로 숨깁니다. (0) | 2022.07.27 |
---|---|
큰 파일 전체 Mmap() (0) | 2022.07.27 |
편백 컴포넌트 테스트 중에 vue 컴포넌트를 랩하려면 어떻게 해야 합니까? (0) | 2022.07.27 |
Firestore에서 문서가 삭제되지 않음 (0) | 2022.07.27 |
vuejs + vuetify + sr + typscript: 오류: {runInNewContext: false}를 사용하는 경우 번들 내보내기가 함수여야 함 (0) | 2022.07.27 |