2012-08-10 17 views
6

Tengo una clase abstracta, para la cual quiero que todas las subclases definan una constante, en función de la implementación, principalmente son metadatos sobre la implementación de clase.subclases de fuerza para incluir constante en la clase abstracta de java

En la superclase:

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

Y luego, en la subclase:

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

¿Hay una manera de forzar a las implementaciones de una clase para declarar una constante?

+1

¡Probablemente vale la pena señalar que una constante con valores potencialmente diferentes no es una constante! Entonces ve con la respuesta de Peters. – TedTrippin

Respuesta

7

Puede forzar a la subclase a definir un método que puede ser una constante para esa clase.

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

Nota: si tiene subclase de sus subclases, estos pueden "olvidar" para anular estos métodos.

+0

estaba a punto de sugerir esto;) –

+2

Lo mejor que puede obtener. Como O.P. no puede hacer exactamente lo que quiere hacer, este es sin duda el mejor enfoque. –

+0

¡Gracias! No pensé en esto (obviamente). No hay forma de asegurar que una implementación sub-sub de la clase estática implemente estos métodos ¿está ahí? –

0

No. No puede.

Incluso no puede declarar la constante en su superclase abstracta sin asignarles valores concretos. En otro caso, obtendrá un error. Debe inicializar los campos finales durante su declaración o en el constructor de la clase.

Puede declarar métodos abstractos que inicializarán sus variables (pero esto será más ofuscado). De esta manera:

protected String OBJECT_NAME = getObjectNameValue(); 

public abstract String getObjectNameValue(); 

Pero en tal caso las variables y los métodos no deben ser estáticos. Porque no puede definir métodos estáticos como abstractos (look here for explanation).

O puede utilizar métodos directamente en lugar de variables como propuso Peter Lawrey, esto será más legible.

0

Esto no funcionará de esa manera. Me defino como éstas funciones abstractas:

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

Y en la subclase:

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; 
} 

Los métodos no son static, pero creo que esto es lo más cerca que puede llegar a lo que quieres.

1

ser que también vaya para una interfazya que no tendrán valores por defecto para la superclase:

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

y tienen sus clases reales implementan la interfaz. Obtienes pruebas más fáciles es una bonificación.

-1

Sé lo que dices.

I, por ejemplo, quieren tener una interfaz (que yo estoy llamando ExecutableList) tengo un campo de cadena contant llamada USER_FRIENDLY_NAME

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 

} 

Por desgracia, esto no es posible en Java. Cuando declara un campo en una interfaz Java, implica los modificadores public, static y final.Un cambio futuro en el Lenguaje de Programación de Java PODRÍA permitir el agregado de abstract, haciendo los modificadores implícitos public abstract static final String USER_FRIENDLY_NAME;, pero si bien podría definir claramente las reglas para esto, el uso de la palabra abstract sería confuso, ya que se entiende que abstract y final definir significados opuestos.

Estoy cruzando los dedos para que una versión futura de Java implemente esto. He oído que los métodos de interfaz privada se agregarán en Java 9 (para usar entre los métodos predeterminados), pero aún no hay palabras sobre esta adición al idioma. Habrá una serie de problemas de compatibilidad hacia atrás para considerar primero, estoy seguro. Si alguien de Oracle lee esto, ¡POR FAVOR DEJEMOS CONSTANTES EN INTERFACES Y DEJAR QUE LAS CLASES/INTERFACES HEREDITARES LAS DEFINEN!

Mientras tanto, su única opción es definir un método String getUserFriendlyName(); en su interfaz o clase abstracta. No tan elegante y tal vez no tan eficiente, pero no tienes otra opción actualmente.

Cuestiones relacionadas