2012-08-10 9 views
6

저는 모든 하위 클래스가 구현을 기반으로 상수를 정의하기를 원하는 추상 클래스가 있습니다. 이는 주로 클래스 구현에 대한 메타 데이터입니다. 슈퍼 클래스에서추상 자바 클래스에서 상수를 포함하도록 강제로 서브 클래스를 지정합니다.

:

protected static final String OBJECT_NAME = "awesome class"; 
protected static final String OBJECT_DEF = "an awesome class that is also great"; 

상수를 선언하는 클래스의 구현을 강제 할 수있는 방법이 있나요 : 서브 클래스의

protected static final String OBJECT_NAME; 
protected static final String OBJECT_DEF; 

그리고?

+1

아마도 잠재적으로 다른 값을 가진 상수는 상수가 아닙니다. 그러니 피터스의 대답으로 가십시오. – TedTrippin

답변

7

하위 클래스가 해당 클래스의 상수가 될 수있는 메서드를 정의하도록 할 수 있습니다.

protected abstract String objectName(); 
protected abstract String objectDef(); 

참고 : 하위 클래스의 하위 클래스가있는 경우 이러한 하위 클래스는 이러한 메서드를 무시할 수 있습니다.

+0

님이 이것을 제안하려고 했음) –

+2

최상의 결과를 얻을 수 있습니다. O.P.는 그가하고 싶은 일을 정확히 수행 할 수 없기 때문에 이것은 확실히 최선의 접근법입니다. –

+0

감사합니다. 이것을 생각하지 않았다 (분명히). 정적 클래스의 하위 하위 구현이 이러한 메서드를 구현한다는 보장 할 방법이 없습니다. –

0

아니요.

구체적인 값을 할당하지 않고 추상 수퍼 클래스에서 상수를 선언 할 수도 없습니다. 다른 경우에는 오류가 발생합니다. 선언하는 동안 또는 클래스 생성자에서 최종 필드를 초기화해야합니다.

변수를 초기화하는 추상 메소드를 선언 할 수 있지만 (더 어렵게됩니다). 이와 같이 :

protected String OBJECT_NAME = getObjectNameValue(); 

public abstract String getObjectNameValue(); 

그러나 이러한 경우 변수와 메소드는 정적이어서는 안됩니다. 왜냐하면 정적 메소드를 추상 (look here for explanation)으로 정의 할 수 없기 때문입니다.

또는 Peter Lawrey가 제안한 변수 대신 직접 메서드를 사용할 수 있습니다.이 코드는 더 쉽게 읽을 수 있습니다.

0

이렇게하면 작동하지 않습니다.

private static final String OBJECT_NAME = "awesome class"; 
private static final String OBJECT_DEF = "bla"; 

protected String objectName(){ 
    return OBJECT_NAME; 
} 

protected String objectDef(){ 
    return OBJECT_DEF; 
} 

방법이 없습니다 static,하지만 난이 당신이 원하는 것을 얻을 수있는 가장 가까운 생각 :

protected abstract String objectName(); 
protected abstract String objectDef(); 

그리고 서브 클래스 : I 추상 함수로 다음을 정의합니다.

Inreface HasObjectNameAndDef { 
    public String getObjectName(); 
    public String getObjectDef(); 
} 

과 실제 클래스는 인터페이스를 구현해야 : 당신은 슈퍼 클래스에 대한 의미있는 디폴트를 가지고 있지 않는 한

1

뿐만 아니라 인터페이스 갈 수 있습니다. 더 쉬운 테스트는 보너스입니다.

-1

나는 당신이 말하는 것을 알고 있습니다. 예를 들어

나는 불행하게도

public interface ExecutableList<T extends ExecutableList<T,E>,E> //This is type parameter 
    extends List<E>,            //self referencing. Trust 
      Comparable<E>,          //me, it has its uses. 
{ 
    /** This would declare a constant but leave it to sub-interfaces/classes to define it. */ 
    abstract String USER_FRIENDLY_NAME; 

    //Define the rest of your interface 

} 

USER_FRIENDLY_NAME라는의 상수 문자열 필드 (나는 ExecutableList를 호출하고)이 인터페이스를 갖고 싶어,이 자바로 할 수 없습니다. Java 인터페이스에서 필드를 선언하면 수정 자 public, staticfinal이 포함됩니다.Java 프로그래밍 언어의 향후 변경으로 인해 abstract이 추가되어 암시 적 수정자인 public abstract static final String USER_FRIENDLY_NAME;을 만들 수 있지만 이에 대한 규칙을 명확하게 정의 할 수 있지만 abstract이라는 단어는 일반적으로 abstractfinal으로 이해되므로 혼란 스럽습니다. 반대 의미를 정의하십시오.

나는 미래 버전의 자바가 이것을 구현할 것이라고 내 손가락을 넘기고있다. 개인 인터페이스 메소드가 Java 9 (기본 메소드를 사용하기 위해)에 추가되지만 언어에 추가 된 내용은 아직 없습니다. 먼저 여러 가지 하위 호환성 문제를 고려해야합니다. 오라클의 누군가가 이것을 읽으면, 인터페이스에서 미국의 선언 상수를 그대로 사용하고 상주하는 클래스/인터페이스를 정의하십시오 !!!

그 동안 유일한 방법은 인터페이스 또는 추상 클래스에 String getUserFriendlyName(); 메소드를 정의하는 것입니다. 우아하지 않고 효과적이지는 않지만 현재 다른 옵션은 없습니다.

관련 문제