2012-08-10 8 views
6

Ho una classe astratta, per cui voglio che tutte le sottoclassi definiscano una costante, in base all'implementazione: sono principalmente metadati sull'implementazione della classe.sottoclassi di forza per includere la costante nella classe java astratta

nella superclasse:

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

E poi nella sottoclasse:

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

C'è un modo per forzare le implementazioni di una classe per dichiarare una costante?

+1

Probabilmente vale la pena notare che una costante con valori potenzialmente diversi non è una costante! Quindi vai con la risposta di Peters. – TedTrippin

risposta

7

È possibile forzare la sottoclasse per definire un metodo che può essere una costante per quella classe.

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

Nota: se si dispone di una sottoclasse delle sottoclassi, questi potrebbero "dimenticare" di sovrascrivere questi metodi.

+0

stava per suggerire questo;) –

+2

Il meglio che puoi ottenere. Poiché l'O.P. non può fare esattamente ciò che vuole fare, questo è sicuramente l'approccio migliore. –

+0

Grazie! Non ho pensato a questo (ovviamente). Non esiste un modo per assicurare un'implementazione sub-sub degli implementatori di classi statiche che questi metodi esistono? –

0

No. Non è possibile.

Non puoi nemmeno dichiarare costante nella tua superclasse astratta senza assegnare loro valori concreti. In altri casi si verificherà un errore. È necessario inizializzare i campi finali durante la loro dichiarazione o nel costruttore della classe.

È possibile dichiarare metodi astratti che inizializzeranno le variabili (ma questo sarà più offuscato). In questo modo:

protected String OBJECT_NAME = getObjectNameValue(); 

public abstract String getObjectNameValue(); 

Ma in tal caso, le variabili e i metodi non devono essere statici. Perché non si definiscono i metodi statici come astratti (look here for explanation).

Oppure è possibile utilizzare i metodi direttamente anziché variabili come proposto da Peter Lawrey, questo sarà più leggibile.

0

Questo non funzionerà in questo modo. Mi definisco questi come funzioni astratte:

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

E nella sottoclasse:

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

I metodi non sono static, ma penso che questo è il più vicino si può arrivare a ciò che si desidera.

1

potrebbe anche andare per un un'interfaccia in quanto non si hanno ragionevoli valori predefiniti per la superclasse:

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

e hanno le classi effettive implementano l'interfaccia. È più facile testare è un bonus.

-1

So cosa stai dicendo.

io per esempio, vuole avere un'interfaccia (che io chiamo ExecutableList) hanno un campo di stringa contant chiamato 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 

} 

Purtroppo, questo non è possibile in Java. Quando si dichiara un campo in un'interfaccia Java, ciò implica i modificatori public, static e final.Una modifica futura al linguaggio di programmazione Java POTREBBE consentire di aggiungere abstract, rendendo così i modificatori impliciti public abstract static final String USER_FRIENDLY_NAME; ma mentre si potevano definire chiaramente le regole per questo, l'uso della parola abstract sarebbe confuso, come in genere sono abstract e final definire significati opposti.

Sto incrociando le dita che una versione futura di Java implementerà questo. Ho sentito che i metodi di interfaccia privata verranno aggiunti in Java 9 (da usare tra i metodi predefiniti) ma non ci sono ancora parole su questa aggiunta alla lingua. Ci sarebbero un numero di problemi di compatibilità con le versioni precedenti da considerare prima, ne sono sicuro. Se qualcuno da Oracle legge questo, PER FAVORE, DICITECI DI DICHIARARE COSTANTI IN INTERFACCE E LASCIARTI LE CLASSI EREDITARIE/INTERFACCE DEFINIRE !!!

Nel frattempo, l'unica opzione è definire un metodo String getUserFriendlyName(); nell'interfaccia o nella classe astratta. Non elegante e forse non così efficace, ma al momento non hai altre opzioni.

Problemi correlati