2012-08-10 6 views
6

Ich habe eine abstrakte Klasse, für die ich möchte, dass alle Unterklassen eine Konstante definieren, basierend auf der Implementierung - es sind hauptsächlich Metadaten über die Klassenimplementierung.force-Unterklassen, die Konstante in abstrakte Java-Klasse enthalten

In der Oberklasse:

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

Und dann in der Unterklasse:

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

Gibt es eine Möglichkeit Implementierungen eine Klasse zu zwingen, eine Konstante zu deklarieren?

+1

Vielleicht ist es bemerkenswert, dass eine Konstante mit möglicherweise unterschiedlichen Werten keine Konstante ist! Also geh mit Peters Antwort. – TedTrippin

Antwort

7

Sie können die Unterklasse zwingen, eine Methode zu definieren, die für diese Klasse eine Konstante sein kann.

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

Hinweis: Wenn Sie eine Unterklasse Ihrer Unterklassen haben, können diese "vergessen", diese Methoden zu überschreiben.

+0

war im Begriff, dies zu empfehlen;) –

+2

Das Beste, was Sie bekommen können. Da der O.P. nicht genau das machen kann, was er tun möchte, ist dies sicherlich der beste Ansatz. –

+0

Danke! Dachte nicht (offensichtlich). Es gibt keine Möglichkeit, eine Sub-Sub-Implementierung der statischen Klassen-Implementierungen zu gewährleisten, diese Methoden gibt es? –

0

Nein. Sie können nicht.

Sie können in Ihrer abstrakten Oberklasse keine Konstante deklarieren, ohne ihnen konkrete Werte zuzuweisen. In anderen Fällen erhalten Sie einen Fehler. Sie sollten die letzten Felder während ihrer Deklaration oder im Klassenkonstruktor initialisieren.

Sie können abstrakte Methoden deklarieren, die Ihre Variablen initialisieren (aber das wird mehr verschleiert). Wie folgt:

protected String OBJECT_NAME = getObjectNameValue(); 

public abstract String getObjectNameValue(); 

Aber in diesem Fall sollten Ihre Variablen und Methoden nicht statisch sein. Weil Sie statische Methoden nicht als abstrakt definieren können (look here for explanation).

Oder Sie können Methoden direkt anstelle von Variablen verwenden, wie Peter Lawrey vorgeschlagen, dies wird besser lesbar sein.

0

Dies wird nicht so funktionieren.

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

Und in der Unterklasse:: Ich würde diese als abstrakte Funktionen definieren

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

Die Verfahren sind nicht static, aber ich denke, das ist in der Nähe, die Sie bekommen, was Sie wollen.

1

könnte genauso gut für eine Schnittstelle gehen wie Sie nicht sinnvoll, Vorgaben für die übergeordnete Klasse haben Sie:

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

und haben Ihre tatsächliche Klassen die Schnittstelle implementieren. Sie bekommen leichteres Testen ist ein Bonus.

-1

Ich weiß, was Sie sagen.

ich zum Beispiel möge eine Schnittstelle haben (was ich ExecutableList nenne) ein contant String-Feld 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 

} 

Leider genannt wird, ist dies in Java nicht möglich. Wenn Sie ein Feld in einer Java-Schnittstelle deklarieren, impliziert dies die Modifikatoren public, static und final.Eine zukünftige Änderung der Java-Programmiersprache könnte ermöglichen, dass abstract hinzugefügt wird, wodurch die implizierten Modifikatoren public abstract static final String USER_FRIENDLY_NAME; gemacht werden, aber während Sie klar Regeln hierfür definieren könnten, wäre die Verwendung des Wortes abstract verwirrend, wie abstract und final typischerweise verstanden werden Definieren Sie entgegengesetzte Bedeutungen.

Ich meine Daumen, dass eine zukünftige Version von Java dies implementieren wird. Ich habe gehört, dass private Schnittstellenmethoden in Java 9 hinzugefügt werden (für die Verwendung zwischen Standardmethoden), aber noch kein Wort zu dieser Ergänzung der Sprache. Es würde eine Reihe von Problemen mit der Rückwärtskompatibilität geben, die ich zuerst betrachten sollte, da bin ich mir sicher. Wenn jemand von Oracle dies liest, LASSEN SIE BITTE UNS KONSTANTEN IN INTERFACES ERKLÄREN UND LASSEN, VERSTEHEN KLASSEN/SCHNITTSTELLEN DEFINIEREN SIE !!!

In der Zwischenzeit ist Ihre einzige Option, eine String getUserFriendlyName(); Methode in Ihrer Schnittstelle oder abstrakten Klasse zu definieren. Nicht so elegant und vielleicht nicht so effecient, aber Sie haben zurzeit keine andere Wahl.

Verwandte Themen